{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "a65a6a90",
   "metadata": {},
   "source": [
    "## 对sympy的学习和使用笔记"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4c627310",
   "metadata": {},
   "source": [
    "### 我的学习前言和动机"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6ca4a7c0",
   "metadata": {},
   "source": [
    "一个简单的积分问题:\n",
    "    \n",
    "    在一个直角坐标系下，有一根定长的动线段。这个线段的一端在y轴上，一端在x轴上。问这个线段划过的图形面积。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "34f6162f",
   "metadata": {},
   "source": [
    "我们假设这个线段的长是单位一。\n",
    "\n",
    "然后我们可以思考一下，这个划出来的图形是如何一步一步变大的。也就是说，这个划出来的曲线面积是如何一步一步变大的。\n",
    "\n",
    "其实我们可以假设这个线段，先是贴在y轴上的，然后慢慢的与y轴产生一个夹角，这个时候就构造出了一个由线段、y轴、x轴围成的三角形。当这个夹角不断变大时，新围成的三角形会有一部分与原三角形重合，一部分突出。如果我们将这些突出部分全部相加，则得到了这个线段划过图形的面积。\n",
    "\n",
    "接下来，我们考虑"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "a4da52e7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\frac{3 \\pi}{32}$"
      ],
      "text/plain": [
       "3*pi/32"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sympy import *\n",
    "x=Symbol(\"x\")\n",
    "integrate((cos(x))**4/2,(x,0,pi/2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "fdde6b00",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\frac{3 \\pi}{32}$"
      ],
      "text/plain": [
       "3*pi/32"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "integrate(3*cos(x)**4*sin(x)**2,(x,0,pi/2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "7805e29a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.0*hyper((-0.5, 0.5), (1.5,), 1)\n",
      "1.0*hyper((-1.5, 1.5), (2.5,), 1)\n",
      "1.0*hyper((-2.5, 2.5), (3.5,), 1)\n",
      "1.0*exp(-2.0*I*pi)*hyper((-3.5, 3.5), (4.5,), 1)\n"
     ]
    }
   ],
   "source": [
    "for i in range(1,8,2):\n",
    "    print(integrate((1-(x)**(2/i))**(i/2),(x,0,1)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "id": "039412b1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.0"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "float(integrate((1-(x)**(2/3))**(3/2),(x,0,1)))-float(3*pi/32)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "335cb10b",
   "metadata": {},
   "source": [
    "这个问题非常的有趣，但是起初我在解决这个问题的时候是花了点时间去计算的，但是效果并不好。\n",
    "\n",
    "主要是我对数学运算的技法掌握的并不严肃，总是会出现这样或那样的一些马虎。\n",
    "\n",
    "但是有了sympy，我就可以更多的将精力花在对数学本质的认识上，而不是基本的繁杂运算上（当然我也会在这方面进行提高）。\n",
    "\n",
    "这就是sympy的好处，把一些特别繁杂的事务性工作帮你解决了。那就进一步开始吧。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "20c037dd",
   "metadata": {},
   "source": [
    "## 安装"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b32eb927",
   "metadata": {},
   "source": [
    "### sympy的环境部署"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a22b2bb7",
   "metadata": {},
   "source": [
    "- 官方推荐的是使用Anaconda安装sympy这个python库\n",
    "\n",
    "这样做有很多的好处。主要就是几点：\n",
    "1、安装更简单，且方便以后进一步管理。\n",
    "2、利于以后与其他的库一起使用。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "36468281",
   "metadata": {},
   "source": [
    "- 如果你的能力非常的强，可以对sympy进行研究和贡献（改进），那么推荐使用git进行部署。\n",
    "\n",
    "这样做的好处是：\n",
    "1、方便与他人合作和修改sympy。\n",
    "2、能随时获得最新的功能。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4b91354a",
   "metadata": {},
   "source": [
    "#### 要注意的地方"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c9c4b684",
   "metadata": {},
   "source": [
    "文档谈到了mpmath这个库。\n",
    "\n",
    "通过文意大致可以推断出以前是直接把mpmath集成在sympy里了，但是为了以后的发展将要逐渐的把mpmath移除出去，所以在使用mpmath的时候官方建议是独立的使用。\n",
    "\n",
    "官方专门给出了一个解决这个问题的方案：\n",
    "```python\n",
    "import sys\n",
    "import mpmath\n",
    "sys.modules['sympy.mpmath']=mpmath\n",
    "```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a3320227",
   "metadata": {},
   "source": [
    "#### 最好的学习还是与大家交流"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "386fbaa8",
   "metadata": {},
   "source": [
    "这一章最后，作者给出了解决遇到问题的一些方案或着说是建议：\n",
    "\n",
    "- Gitter上提问\n",
    "- 相应的E-mail\n",
    "- github上提issue"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d1e163c4",
   "metadata": {},
   "source": [
    "### 章末总结"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ffadddcc",
   "metadata": {},
   "source": [
    "这一章主要是让读者能够在自己的电脑上安装上sympy的运行环境。\n",
    "\n",
    "推荐了使用Anaconda来安装和管理sympy。\n",
    "\n",
    "同时也给出了在学习和使用sympy的过程中遇到问题如何进行应对和处理的建议。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a95d985f",
   "metadata": {},
   "source": [
    "## 总体介绍"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "55b817b8",
   "metadata": {},
   "source": [
    "这一章是简单的教程。\n",
    "\n",
    "在这一章开始的时候，作者强调了读者有基本的python知识和能力。\n",
    "\n",
    "当然，作者也贴心的给出了直接在浏览器上使用sympy的方法。\n",
    "> 不过考虑到我们已经安装了Anaconda，那就直接在jupyter上边写边操作了。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d88dcf10",
   "metadata": {},
   "source": [
    "### 本章开始之前"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2ff3a4f7",
   "metadata": {},
   "source": [
    "能够使用sympy环境进行简单的入门操作，比如下面的一段代码："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "4fb3c4c8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\int e^{x} \\cos{\\left(x \\right)}\\, dx = \\frac{e^{x} \\sin{\\left(x \\right)}}{2} + \\frac{e^{x} \\cos{\\left(x \\right)}}{2}$"
      ],
      "text/plain": [
       "Eq(Integral(exp(x)*cos(x), x), exp(x)*sin(x)/2 + exp(x)*cos(x)/2)"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 这个是文档上简单的例子\n",
    "from sympy import *\n",
    "x=symbols(\"x\")\n",
    "a=Integral(cos(x)*exp(x),x)\n",
    "Eq(a,a.doit())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1df31e9f",
   "metadata": {},
   "source": [
    "接下来，文档提到了作业的问题，接下来的教程都是与Scipy的一些问题有关的。并给出了相关的资料与作业的[网址](http://certik.github.io/scipy-2013-tutorial/html/index.html)。\n",
    "\n",
    "由于作者强烈推荐了相关的exercise，所以我们还是去做一做作业会比较好。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b1c1ce43",
   "metadata": {},
   "source": [
    "这一章的主要任务是简单的介绍sympy在整体的一些功能，但是会很简单而不深入。主要是为了给从未接触过sympy的人快速上手使用提供帮助。\n",
    "这一章后面的内容基本上就是API文档，供读者进一步处理具体复杂的问题时使用和查阅。\n",
    "\n",
    "作者强调了几个关键的点：\n",
    "\n",
    "- 简单，有趣。\n",
    "- 最好的方式呈现sympy的功能。\n",
    "- 按照逻辑顺序介绍基本的概念。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "823bd86c",
   "metadata": {},
   "source": [
    "### sympy介绍"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "57f662d7",
   "metadata": {},
   "source": [
    "#### 什么是符号运算"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "691210f6",
   "metadata": {},
   "source": [
    "说到底就是我们以前接触的计算机软硬件总喜欢把公式计算出近似的数值结果，而不是对数学符号进行运算给出精确的公式。\n",
    "\n",
    "然后作者给出了具体的例子（其实这个例子非常重要，我之前一直忽略了这些，导致以后学习sympy走了些弯路）：\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "9e1270b1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3.0\n",
      "2.8284271247461903\n",
      "2*sqrt(2)\n"
     ]
    }
   ],
   "source": [
    "import math \n",
    "print(math.sqrt(9))\n",
    "# this time, it can give exact answer.\n",
    "print(math.sqrt(8))\n",
    "# this time, it give the approximate answer.\n",
    "\n",
    "# let's see the sympy's answer\n",
    "import sympy\n",
    "print(sympy.sqrt(8))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "efd7be18",
   "metadata": {},
   "source": [
    "#### 更有趣的例子"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "42edc7a7",
   "metadata": {},
   "source": [
    "符号计算系统（Symbolic computation systems）又叫计算机代数系统（computer algebra systems or just CASs）sympy是可以进行含参数符号运算的。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "a1aa178c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle x + 2 y$"
      ],
      "text/plain": [
       "x + 2*y"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sympy import symbols\n",
    "x,y=symbols(\"x,y\")\n",
    "expr=x+2*y\n",
    "expr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "37a08e6e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle x + 2 y + 1$"
      ],
      "text/plain": [
       "x + 2*y + 1"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "expr+1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "2cdf2847",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle 2 y$"
      ],
      "text/plain": [
       "2*y"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "expr-x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "466ee0cc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle x \\left(x + 2 y\\right)$"
      ],
      "text/plain": [
       "x*(x + 2*y)"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x*expr"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "33d11417",
   "metadata": {},
   "source": [
    "上式没有展开是因为sympy默认是这样的，不过我们可以在不同的表达式展开风格中进行切换："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "25c88e22",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle x^{2} + 2 x y$"
      ],
      "text/plain": [
       "x**2 + 2*x*y"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sympy import expand, factor\n",
    "expanded_expr=expand(x*expr)\n",
    "expanded_expr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "8f5fb46d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle x \\left(x + 2 y\\right)$"
      ],
      "text/plain": [
       "x*(x + 2*y)"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "factor(expanded_expr)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1f8a5edb",
   "metadata": {},
   "source": [
    "#### 符号运算的强大力量"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "68b8f8a0",
   "metadata": {},
   "source": [
    "\n",
    "开始秀操作了，前方高能，请站稳扶好。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "84f2e06d",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "4afc2775",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sympy import *\n",
    "\"\"\"\n",
    "因为我们是在jupyter里，所以下面的一句其实没有起作用，但\n",
    "如果是在命令行里，作用就大了。\n",
    "\"\"\"\n",
    "init_printing(use_unicode=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "5871b951",
   "metadata": {},
   "outputs": [],
   "source": [
    "x, t, z, nu =symbols(\"x, t, z, nu\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "207f7eb2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle e^{x} \\sin{\\left(x \\right)} + e^{x} \\cos{\\left(x \\right)}$"
      ],
      "text/plain": [
       " x           x       \n",
       "ℯ ⋅sin(x) + ℯ ⋅cos(x)"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "diff(sin(x)*exp(x),x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "2d0a9b0d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAE8AAAAVCAYAAAAHIbMXAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAD6ElEQVRYCeWY61EcMQyA95gUQKADrgMgHUAHPCoAOgjDP/5loANIB0AH0AGPDkIHgeuAfJ9j7/g2u8vt7sEwRDM6+SHJsiTL3hu9vLwUXeD4+Ph75B9DT8AtMLSZe4xzH5Jg30pfG+tkF7rsEgU67gp6Cl0Cz2J7nfYq+GEh2j7ERh2fEifss5PzkJigIGXXIv3r6K09xq9iuzNBVsOewf3OwjMIoNfTsQwdYuONS+U2dnIegueZrRu0gzGMP2TjfZorCBmMtT7CbTLYpt4j6GEb3yxz6PDEHUSdRSfnpQUQNv3LLKTv5nsD8kb1K/Sgt5JmQevyWfN05xl1qXN25+kg8DkutQtNx9eheUR1EnXPm+xgd35iBumPutS5+GVWTTA/ghegRTPUuthWxWDnzWpHFz7ss9blQe4i3sarzp0p57FYqA9M/I6SPkEOGQ9ZAc2PVSigka+VIOcxt0aqxzWEXcbXQI/8JSi9ob8NLaDK/AQdvwDTs4hm8Q28hcca1AabTDbaiby2pEtKnXug63myBNeou2TUuVk6DyY353neph0uAKgbOAJ7ZxY6NPAE6kZKoB8CATWKOvG+nKRBXxsc/wVdAldpB2dBtese6rOpLbN8QrXVO+1KdniiDJYOM2FSbatznjZtLPBTwKi3PYoqy29OHRqOKLQvuIF19KaMS3qqm3pKExWqczaQLzeR2ah9beCatXrRYcaFwh8VTKAe81QfDVg+H9kCUedKyry0kUWUpofgMgzX9BvTPtfW1FYedDHfceoyGOmh3SRWHb+rDsR+NSBVNh2gU+rgDnvyrPWZ9MBY4IeG8lEnyJhy5YVhBLtuqEFv7bCGHYFG1mia4edgXkMZfj9g7YfKajv0f1TGmrohKOHYRo7bJs4h4xhpSSig1pExOKKr0/ZpW7veEsz417KzwA6TR768NHgKm2Qdf0rOMw09pv8ACsyWIaCD0o0W9KDTuqKh1sO3BPcVgpcvolNAS1KqmQazfPRHXr9KJrlc1jbzHpPzPEpJUeCJC1gLq+kd5jv+aEg1ivar9bTK4zIa2he03SdIFdyr+BTtMkNLYMy5tpMY6uMo/SWFgBeF2ec1LBid195RfzlbfqMhPlPS21Fu1wmXEfNmpvUwBU+HpvdWqpNmgOPWJDPJTJE/jKOjtrhH3ZdQ36sl0DdIJkzYK/1T0BOmnT6ZdGp5hOlPAXPKHZTOm5r9RJ240fLtOnRr6DN4Bn6cju1QnR9Z3gwzU+cFfjCoc/Y/Bua18nvrIUO8nPxTw4wZBFGHusJD+n/IPB1mTfTyGwrqKLP409e85K2YNVvQXpcgcl6oU9/SfwDp3X1UGYYoPQAAAABJRU5ErkJggg==",
      "text/latex": [
       "$\\displaystyle e^{x} \\sin{\\left(x \\right)}$"
      ],
      "text/plain": [
       " x       \n",
       "ℯ ⋅sin(x)"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "integrate(exp(x)*(sin(x)+cos(x)),x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "4ac33429",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAADoAAAAuCAYAAAB5/AqlAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAER0lEQVRoBe2a7VHcMBCG7zIpgKSEowM+KgjpACYdcB2EyS/4l0k6ACpIQgehgwQ6gBIydEDeRyd5ZEu2JVs2zIBmhKTVandf7WrPtlg+Pj4uxpSzs7Mdrf+k+jlVjtYsU3lL8b0tIOibZJzI+JMCsiYTMQqo9eZC7e1kFjYEW503DXLvcBRQSf+iikfnLOjbzd3cwUClaCWFK7XXPkpLd2G8p7l/qoT2aK9LBvlgMUTWYKAYbyu6TZEBgD9X+9GSMAoP3EBTrW2K48loB0fQmwwlFasM3tJgL2I4oNYVozriYUMeVH/59Ny+5EQjKFXOIKASDqCvESUHot3JKDbCL3hyyxrr03P6QQTlLM4GakEcqL2KKALQvebwYKw0NyDGE9CszlgEBbxthCFntPWcyKCjFkWDk4iVF40g6YN+rNq1gRfiW9eAinCoRQ9qu5LGoea3rQG9jXgByflymbh3jc+g9YAggppnH5AUNheefdUfqmR6xgaD1plsXwEVgUc4vHWvuqsaFMtzHkx0E0hCV1r7vZutdTaIIMli8/6oNcfH2aWWY0OeuFZb+zkzZ1REFl7YumPHGgZlrblkg8XLpqA8GtKiEx0Y1lXgwbaqaHyr6ucIfrpwEAXPur4h8McBZeGDxi6Tsou1onnOQrI3Lf97tdVvqi9QdCLoUtWFoD9t+panU6d4cBK2u4Kj/LGhG6COwzKwe+ziytFtyxmr7WxjvhpqLWd9W23lSeQ5mWpLRhBn93elfJMPvOGmWwNqZ90OV8lDhmE45yzYqaZEC2JfbbXe8iCDx8GF5opEkORsSRyR9hO5rogeHIcAqJiIbzLWsRXEekLZhTXjaBE/UUDy4eGAR8Gqisb5rm2UHY+JIEDGfreD41JlXS3wC15lVwAL8L9NI31mr08IARYDmqWWBb1JdMFPBJifEOlKjSAANSPHT1Ka3pRl2xcGKeOdD6MBemQBb1YV/ivZbBAb+059fsfR/YF+KVVB6HqCCVXOAKERpGuPr0TX5QUiCG+mRlCy7lagUkgIEG7N0EgWnsooXeQEdJELqA64umVK2xk10mVA9AmpjOpAChFEIpskglo9GpgxMWHqCGpNRhPjml38s/Ho1MhfDNDl6enpuE/1U7uikPzXM1poI5+NmBdzRl+BPpuYK2RI5yNgIR1GjJ58Vuq45+Y99XkJL3InYxT0/Jkl61qQsTsZvhuVuJPpgWk/jvVyjWfgbcS8VDtRAo93ed8cdSfj5PW1cyUjXqqnupPpw2jm5wLK+2bs244zkhf8ScssZ7QNgcL3TnN8Bp38nzfm8miAVeD4tutn4oCnJOHJgArE2DuZrH14ktCVN7lmIGSD769Z1mcwz+5RgeMbbuudTIbtWayzAhVIPmW23slkWZ7JPBtQgST5dN7JZNqexT7LGRXIlazia7y5hW5YyG128g16Y23ycK6H+iF3MskgUhj/A8zGmJ7B12wmAAAAAElFTkSuQmCC",
      "text/latex": [
       "$\\displaystyle \\frac{\\sqrt{2} \\sqrt{\\pi}}{2}$"
      ],
      "text/plain": [
       "√2⋅√π\n",
       "─────\n",
       "  2  "
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "integrate(sin(x**2),(x,-oo,oo))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "e7ef4dce",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAAgAAAAOCAYAAAASVl2WAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAZElEQVQYGWP8//8/Aww0NDQYAdmrgdgYyP4AEmcBMgSA9GwgfgfEJkCsBMRwAFIAUhkKEgGyy4AUyBQ4YIKzcDBGFUACBj0chKHhJQQLN0ZQZAGDGBRBIOACxKC4OQfE94B4NwDm+hiAOyllRAAAAABJRU5ErkJggg==",
      "text/latex": [
       "$\\displaystyle 1$"
      ],
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "limit(sin(x)/x,x,0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "12343a7d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAGMAAAAlCAYAAABWOlfkAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADa0lEQVRoBe2b4VEbMRCF7UwKIOkg0AGQDpwOYOgAOgiTX/a/TNKB0wJ0ENIB0EHoIIEOkvcxuoss3110trR3ZrQzGsnSWrv3nnb37gzT+Xx+MplMrtR8uVgsFt/8iTJOh4CwXWq382DHN1NHxpkUToPF8tEIAWH/KFPvXhnZK2YiEChkRIBkpVLIsEI6ws7rCJ1BVJRHD2X4Lta49Kexujn0Uvg7WjIE2Be1I13kfQ7wMuy5tb+jTFPulE12hYhU/o6SDJ3aT2qctF2RJP6Ojgydsn0xsK/+ZheYSOnvGGvGpUig1eIuuJo71sJvtUvNj6GeJPN3VGQI3D2BfKz+omLCEbFU/8GbI4XdMac2WATJdlJ/x5amAPlzBbrrmavJYU4gcBqf1MJ3aixbSlJ/R0OGO2Uz9dcBmjN9/unW/SUiYk/z1BhzyeHvaMgQmm13JID+oIsnEpqEVDGEJPfXpGYISF7TP6nvyu8nWj8IUdVc29tkntAnWk9exLXnIP5mJ0MX9lGYcYoe1I7U1sTpLNcWWiakDxGkp+oOq0Wz//SQ/mZNUw40fqSiHbrPTQjxY9bXpoWWOQr3dc/vtGz1b3pofzsjQ86Rj3+o9cnLp/rec+rweu6QqghZSTvS4RevPlGBLjVkZR/NbS1D+/s/Miiajamlz5XrIqkXRMe5ep6uSVmVkGqibOh7EPdWff3MUW2Sstf+g/ibNU0FAHFPjtR5XhdNoSTdQHqnON0D9XVEaAyx1I4cYu6vGRkCjWjgboroqNIehT18yFsDVvoU7PfqayKdEmTyaqQWb+96bpOB9jHx1/etM035ionGnLaZGoRwsbfqO6NC65x8CvaNxmFt4SGxLvwaQ/Kj+nu1qNQn/S7J6m9o2CwyMCyAiAyKOxFBq1KBhq3yXSsQQr0I2wqR2p/PkMyTOcRsJbn9DZ2zjgzsk5Y46dwRAVynSGftQbDrC+irkb5SSVZ/fSdNIwPDAop3T0RHmP9ZTiXUl5Wo2XRjI3+f3RsiMiAkRT5vxFd7k55+NS5uOJnTX98l88jwjWcac3NQF/VMNrJs++LI2FUiYPfFkZHlyBptWsgwAjrGTCEjBiUjnUKGEdAxZgoZMSgZ6RQyjICOMVPIiEHJSKd6AuePAf54Nsv/9HlgpB4Ka94+89JzRf4COMGPgdTQUmMAAAAASUVORK5CYII=",
      "text/latex": [
       "$\\displaystyle \\left[ - \\sqrt{2}, \\  \\sqrt{2}\\right]$"
      ],
      "text/plain": [
       "[-√2, √2]"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "solve(x**2-2,x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "b408edda",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle y{\\left(t \\right)} = C_{2} e^{- t} + \\left(C_{1} + \\frac{t}{2}\\right) e^{t}$"
      ],
      "text/plain": [
       "           -t   ⎛     t⎞  t\n",
       "y(t) = C₂⋅ℯ   + ⎜C₁ + ─⎟⋅ℯ \n",
       "                ⎝     2⎠   "
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y=Function('y')\n",
    "dsolve(Eq(y(t).diff(t,t)-y(t),exp(t)),y(t))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "cc7678d9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle \\left\\{ \\frac{3}{2} - \\frac{\\sqrt{17}}{2} : 1, \\  \\frac{3}{2} + \\frac{\\sqrt{17}}{2} : 1\\right\\}$"
      ],
      "text/plain": [
       "⎧3   √17     3   √17   ⎫\n",
       "⎨─ - ───: 1, ─ + ───: 1⎬\n",
       "⎩2    2      2    2    ⎭"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Matrix([[1,2],[2,2]]).eigenvals()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "f8eeb5cc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle \\frac{\\sqrt{2} \\sqrt{z} j_{\\nu - \\frac{1}{2}}\\left(z\\right)}{\\sqrt{\\pi}}$"
      ],
      "text/plain": [
       "√2⋅√z⋅jn(ν - 1/2, z)\n",
       "────────────────────\n",
       "         √π         "
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "besselj(nu,z).rewrite(jn)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "415e4a9f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'\\\\int\\\\limits_{0}^{\\\\pi} \\\\cos^{2}{\\\\left(x \\\\right)}\\\\, dx'"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "latex(Integral(cos(x)**2,(x,0,pi)))\n",
    "# 这里的结果稍微有些变化。可能是环境不一样的原因。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ab9d1ac8",
   "metadata": {},
   "source": [
    "#### 为什么是sympy？！"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b1a42145",
   "metadata": {},
   "source": [
    "主要就是那么几点：\n",
    "\n",
    "- 开放源代码，而且是BSD license，保证完全免费。\n",
    "- 使用python作为开发语言编写，好学易懂，让你专注于数学本身。\n",
    "- 独立轻巧，而不是像Sage这样的大杂烩。\n",
    "- 可以被用作library，对环境的要求最低，也便于使用者做进一步的调用。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2cdcd74e",
   "metadata": {},
   "source": [
    "### 小贴士"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d301b773",
   "metadata": {},
   "source": [
    "- sympy尽一切可能使用python相同的语法，继承python的一切可以继承的东西。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "715b8d24",
   "metadata": {},
   "source": [
    "#### 代数符号"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "27ff7a6c",
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'x' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m/var/folders/dx/_crdzvnd0cg5f4sgbnvzvvgh0000gn/T/ipykernel_71551/2745538105.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m      2\u001b[0m \u001b[0;31m# variables are not defined automatically\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      3\u001b[0m \u001b[0;31m# !你只有在中断后再运行才能看到错误。\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0mx\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m: name 'x' is not defined"
     ]
    }
   ],
   "source": [
    "from sympy import *\n",
    "# variables are not defined automatically\n",
    "# !你只有在重启内核后再运行才能看到错误。\n",
    "x+1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "d04e59fa",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle x + 1$"
      ],
      "text/plain": [
       "x + 1"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x=symbols(\"x\")\n",
    "x+1"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "466c9a8f",
   "metadata": {},
   "source": [
    "**这里需要注意的是sympy的symbol和python的symbol是又区别的！**\n",
    "\n",
    "这里作者使用了一个小例子进行了说明："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "cbac679f",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'sympy.core.symbol.Symbol'>\n",
      "x + 1\n"
     ]
    }
   ],
   "source": [
    "x=symbols(\"x\")\n",
    "print(type(x))\n",
    "expr=x+1\n",
    "x=2\n",
    "print(expr)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4d312957",
   "metadata": {},
   "source": [
    "这里前面的x是sympy的symbol，而后面的x是python的symbol。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "71f82134",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "int"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b752e372",
   "metadata": {},
   "source": [
    "还有一点，就是：\n",
    "\n",
    "**如果变量参数发生了变化，之前就包含这个变量的表达式和python的基本语法规律一样不会自行发生变化。**\n",
    "\n",
    "例如："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "67a15b9c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'abcdef'"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x=\"abc\"\n",
    "expr=x+\"def\"\n",
    "expr\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "dc780011",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'abcdef'"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x=\"ABC\"\n",
    "expr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "3a83b362",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle 3$"
      ],
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 如果要进行替换，可以使用subs函数\n",
    "x=symbols(\"x\")\n",
    "expr=x+1\n",
    "expr.subs(x,2)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "9c451f09",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle x + 1$"
      ],
      "text/plain": [
       "x + 1"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "expr"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1ab82ddc",
   "metadata": {},
   "source": [
    "#### 相等符号"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "258dfb2f",
   "metadata": {},
   "source": [
    "sympy的相等与python的相等确实在很多地方都不相同。这个需要重点的提出来进行说明。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "6d223553",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sympy import *\n",
    "x=symbols(\"x\")\n",
    "x+1==4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "f9e11c85",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x=3\n",
    "x+1==4"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "36674521",
   "metadata": {},
   "source": [
    "**在sympy，我们使用Eq来代表代数符号的相等。**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "b85fa1ab",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle x + 1 = 4$"
      ],
      "text/plain": [
       "Eq(x + 1, 4)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x=symbols(\"x\")\n",
    "Eq(x+1,4)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b072e348",
   "metadata": {},
   "source": [
    "* 进一步的说明："
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5ed10d0c",
   "metadata": {},
   "source": [
    "比如我们想知道是否有：$(x+1)^2=x^2+2x+1$,那么我们看看不同的处理方式会有什么结果："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "54fe1dc6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(x+1)**2==x**2+2*x+1"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fb22de58",
   "metadata": {},
   "source": [
    "事实上，判断两个代数表达式是否相等在理论上被证明是不可能的。\n",
    "\n",
    "不过对一般的表达式我们还是可以判断的。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "98d314d6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle x$"
      ],
      "text/plain": [
       "x"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "6bc00066",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle 0$"
      ],
      "text/plain": [
       "0"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a=(x+1)**2\n",
    "b=x**2+2*x+1\n",
    "simplify(a-b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "4f1310b7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle 4 x$"
      ],
      "text/plain": [
       "4*x"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c=x**2-2*x+1\n",
    "simplify(a-c)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "904196ab",
   "metadata": {},
   "source": [
    "这里还有equals函数可以用来通过检查随机点的数值计算值来判断两个表达式是否相等。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "d07dc24a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a=cos(x)**2-sin(x)**2\n",
    "b=cos(2*x)\n",
    "a.equals(b)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fbb805ad",
   "metadata": {},
   "source": [
    "#### 关于^和/的说明"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dac66286",
   "metadata": {},
   "source": [
    "在python里^是Xor的符号，而不是幂次的符号。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "bf0a0b30",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n"
     ]
    },
    {
     "data": {
      "text/latex": [
       "$\\displaystyle x \\veebar y$"
      ],
      "text/plain": [
       "x ^ y"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print(True^False)\n",
    "print(True^True)\n",
    "# 接下来的最好在jupyter的终端里运行，这样符号不会失真。\n",
    "x,y = symbols(\"x y\")\n",
    "Xor(x,y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "6adfed3c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "sympy.core.function.FunctionClass"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(Xor)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9682bdc8",
   "metadata": {},
   "source": [
    "接下来要讲到关于语法糖的事情。\n",
    "\n",
    "总之就是：**如果出现sympy的类和python的类相互运算时，sympy会自动将python类转为sympy类，然后得到的结果就是sympy类。但是，如果整个过程完全没有sympy的类参与，那么将得到python类。**\n",
    "\n",
    "比如："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "ec5e6f5f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "sympy.core.numbers.Integer"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(Integer(1)+1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "1ba05cdd",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "int"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(1+1)\n",
    "# 不同的环境里结果会有些不一样。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "21bf56ac",
   "metadata": {},
   "source": [
    "- 因为sympy专注于数学而不是程序，所以在两个整数相除时，程序上是得到浮点数，而数学上是得到有理数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "e473928d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\frac{1}{3}$"
      ],
      "text/plain": [
       "1/3"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Integer(1)/Integer(3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "7bd0ca1a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "sympy.core.numbers.Rational"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(Integer(1)/Integer(3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "0a94c41e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1/2\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "abc.ABCMeta"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 这个是对python2说的。\n",
    "from __future__ import division\n",
    "1/2\n",
    "# 事实上现在python已经有了Fraction类\n",
    "from fractions import Fraction\n",
    "print(Fraction(1/2))\n",
    "type(Fraction)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2f38e7e2",
   "metadata": {},
   "source": [
    "如果在输入表达式时使用python的int/int类型，也会出现这样的情况。这个时候我们也应该使用Rational来处理。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "55e33783",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle x + 0.333333333333333$"
      ],
      "text/plain": [
       "x + 0.333333333333333"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x+1/3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "726c8dd9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle x + \\frac{6004799503160661}{18014398509481984}$"
      ],
      "text/plain": [
       "x + 6004799503160661/18014398509481984"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x+Rational(1/3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a610490a",
   "metadata": {},
   "source": [
    "> 当然这里也出现了一些问题，$\\frac{1}{3}$变成了两个非常大的整数的比值。这是计算机存储数值结果的有限性导致的。我们可以通过限定分母的大小来解决问题。\n",
    "\n",
    "> 这个时候是降低了精确度，但是却反而是绝对精确的。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "6574f1f5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\n",
      "22/7\n",
      "311/99\n",
      "355/113\n"
     ]
    }
   ],
   "source": [
    "# from fractions import Fraction\n",
    "import math\n",
    "# print the pi's similar numeric value.\n",
    "# 看看计算机是如何得到祖冲之关于圆周率的近似分数的。\n",
    "print(Rational(math.pi).limit_denominator(1))\n",
    "print(Rational(math.pi).limit_denominator(10))\n",
    "print(Rational(math.pi).limit_denominator(100))\n",
    "print(Rational(math.pi).limit_denominator(1000))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "3269efde",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle x + \\frac{1}{3}$"
      ],
      "text/plain": [
       "x + 1/3"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x+Rational(1/3).limit_denominator(100000)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "e2988fbe",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on class Rational in module sympy.core.numbers:\n",
      "\n",
      "class Rational(Number)\n",
      " |  Rational(p, q=None, gcd=None)\n",
      " |  \n",
      " |  Represents rational numbers (p/q) of any size.\n",
      " |  \n",
      " |  Examples\n",
      " |  ========\n",
      " |  \n",
      " |  >>> from sympy import Rational, nsimplify, S, pi\n",
      " |  >>> Rational(1, 2)\n",
      " |  1/2\n",
      " |  \n",
      " |  Rational is unprejudiced in accepting input. If a float is passed, the\n",
      " |  underlying value of the binary representation will be returned:\n",
      " |  \n",
      " |  >>> Rational(.5)\n",
      " |  1/2\n",
      " |  >>> Rational(.2)\n",
      " |  3602879701896397/18014398509481984\n",
      " |  \n",
      " |  If the simpler representation of the float is desired then consider\n",
      " |  limiting the denominator to the desired value or convert the float to\n",
      " |  a string (which is roughly equivalent to limiting the denominator to\n",
      " |  10**12):\n",
      " |  \n",
      " |  >>> Rational(str(.2))\n",
      " |  1/5\n",
      " |  >>> Rational(.2).limit_denominator(10**12)\n",
      " |  1/5\n",
      " |  \n",
      " |  An arbitrarily precise Rational is obtained when a string literal is\n",
      " |  passed:\n",
      " |  \n",
      " |  >>> Rational(\"1.23\")\n",
      " |  123/100\n",
      " |  >>> Rational('1e-2')\n",
      " |  1/100\n",
      " |  >>> Rational(\".1\")\n",
      " |  1/10\n",
      " |  >>> Rational('1e-2/3.2')\n",
      " |  1/320\n",
      " |  \n",
      " |  The conversion of other types of strings can be handled by\n",
      " |  the sympify() function, and conversion of floats to expressions\n",
      " |  or simple fractions can be handled with nsimplify:\n",
      " |  \n",
      " |  >>> S('.[3]')  # repeating digits in brackets\n",
      " |  1/3\n",
      " |  >>> S('3**2/10')  # general expressions\n",
      " |  9/10\n",
      " |  >>> nsimplify(.3)  # numbers that have a simple form\n",
      " |  3/10\n",
      " |  \n",
      " |  But if the input does not reduce to a literal Rational, an error will\n",
      " |  be raised:\n",
      " |  \n",
      " |  >>> Rational(pi)\n",
      " |  Traceback (most recent call last):\n",
      " |  ...\n",
      " |  TypeError: invalid input: pi\n",
      " |  \n",
      " |  \n",
      " |  Low-level\n",
      " |  ---------\n",
      " |  \n",
      " |  Access numerator and denominator as .p and .q:\n",
      " |  \n",
      " |  >>> r = Rational(3, 4)\n",
      " |  >>> r\n",
      " |  3/4\n",
      " |  >>> r.p\n",
      " |  3\n",
      " |  >>> r.q\n",
      " |  4\n",
      " |  \n",
      " |  Note that p and q return integers (not SymPy Integers) so some care\n",
      " |  is needed when using them in expressions:\n",
      " |  \n",
      " |  >>> r.p/r.q\n",
      " |  0.75\n",
      " |  \n",
      " |  If an unevaluated Rational is desired, ``gcd=1`` can be passed and\n",
      " |  this will keep common divisors of the numerator and denominator\n",
      " |  from being eliminated. It is not possible, however, to leave a\n",
      " |  negative value in the denominator.\n",
      " |  \n",
      " |  >>> Rational(2, 4, gcd=1)\n",
      " |  2/4\n",
      " |  >>> Rational(2, -4, gcd=1).q\n",
      " |  4\n",
      " |  \n",
      " |  See Also\n",
      " |  ========\n",
      " |  sympy.core.sympify.sympify, sympy.simplify.simplify.nsimplify\n",
      " |  \n",
      " |  Method resolution order:\n",
      " |      Rational\n",
      " |      Number\n",
      " |      sympy.core.expr.AtomicExpr\n",
      " |      sympy.core.basic.Atom\n",
      " |      sympy.core.expr.Expr\n",
      " |      sympy.core.basic.Basic\n",
      " |      sympy.printing.defaults.Printable\n",
      " |      sympy.core.evalf.EvalfMixin\n",
      " |      builtins.object\n",
      " |  \n",
      " |  Methods defined here:\n",
      " |  \n",
      " |  __abs__(self)\n",
      " |  \n",
      " |  __add__(self, other)\n",
      " |  \n",
      " |  __ceil__(self)\n",
      " |  \n",
      " |  __eq__(self, other)\n",
      " |      Return a boolean indicating whether a == b on the basis of\n",
      " |      their symbolic trees.\n",
      " |      \n",
      " |      This is the same as a.compare(b) == 0 but faster.\n",
      " |      \n",
      " |      Notes\n",
      " |      =====\n",
      " |      \n",
      " |      If a class that overrides __eq__() needs to retain the\n",
      " |      implementation of __hash__() from a parent class, the\n",
      " |      interpreter must be told this explicitly by setting __hash__ =\n",
      " |      <ParentClass>.__hash__. Otherwise the inheritance of __hash__()\n",
      " |      will be blocked, just as if __hash__ had been explicitly set to\n",
      " |      None.\n",
      " |      \n",
      " |      References\n",
      " |      ==========\n",
      " |      \n",
      " |      from http://docs.python.org/dev/reference/datamodel.html#object.__hash__\n",
      " |  \n",
      " |  __floor__(self)\n",
      " |  \n",
      " |  __ge__(self, other)\n",
      " |      Return self>=value.\n",
      " |  \n",
      " |  __getnewargs__(self)\n",
      " |  \n",
      " |  __gt__(self, other)\n",
      " |      Return self>value.\n",
      " |  \n",
      " |  __hash__(self)\n",
      " |      Return hash(self).\n",
      " |  \n",
      " |  __int__(self)\n",
      " |  \n",
      " |  __le__(self, other)\n",
      " |      Return self<=value.\n",
      " |  \n",
      " |  __lt__(self, other)\n",
      " |      Return self<value.\n",
      " |  \n",
      " |  __mod__(self, other)\n",
      " |  \n",
      " |  __mul__(self, other)\n",
      " |  \n",
      " |  __ne__(self, other)\n",
      " |      ``a != b``  -> Compare two symbolic trees and see whether they are different\n",
      " |      \n",
      " |      this is the same as:\n",
      " |      \n",
      " |      ``a.compare(b) != 0``\n",
      " |      \n",
      " |      but faster\n",
      " |  \n",
      " |  __neg__(self)\n",
      " |  \n",
      " |  __radd__ = __add__(self, other)\n",
      " |  \n",
      " |  __rmod__(self, other)\n",
      " |  \n",
      " |  __rmul__ = __mul__(self, other)\n",
      " |  \n",
      " |  __rsub__(self, other)\n",
      " |  \n",
      " |  __rtruediv__(self, other)\n",
      " |  \n",
      " |  __sub__(self, other)\n",
      " |  \n",
      " |  __truediv__(self, other)\n",
      " |  \n",
      " |  as_coeff_Add(self, rational=False)\n",
      " |      Efficiently extract the coefficient of a summation.\n",
      " |  \n",
      " |  as_coeff_Mul(self, rational=False)\n",
      " |      Efficiently extract the coefficient of a product.\n",
      " |  \n",
      " |  as_content_primitive(self, radical=False, clear=True)\n",
      " |      Return the tuple (R, self/R) where R is the positive Rational\n",
      " |      extracted from self.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy import S\n",
      " |      >>> (S(-3)/2).as_content_primitive()\n",
      " |      (3/2, -1)\n",
      " |      \n",
      " |      See docstring of Expr.as_content_primitive for more examples.\n",
      " |  \n",
      " |  as_numer_denom(self)\n",
      " |      expression -> a/b -> a, b\n",
      " |      \n",
      " |      This is just a stub that should be defined by\n",
      " |      an object's class methods to get anything else.\n",
      " |      \n",
      " |      See Also\n",
      " |      ========\n",
      " |      \n",
      " |      normal: return ``a/b`` instead of ``(a, b)``\n",
      " |  \n",
      " |  ceiling(self)\n",
      " |  \n",
      " |  factors(self, limit=None, use_trial=True, use_rho=False, use_pm1=False, verbose=False, visual=False)\n",
      " |      A wrapper to factorint which return factors of self that are\n",
      " |      smaller than limit (or cheap to compute). Special methods of\n",
      " |      factoring are disabled by default so that only trial division is used.\n",
      " |  \n",
      " |  floor(self)\n",
      " |  \n",
      " |  gcd(self, other)\n",
      " |      Compute GCD of `self` and `other`.\n",
      " |  \n",
      " |  lcm(self, other)\n",
      " |      Compute LCM of `self` and `other`.\n",
      " |  \n",
      " |  limit_denominator(self, max_denominator=1000000)\n",
      " |      Closest Rational to self with denominator at most max_denominator.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy import Rational\n",
      " |      >>> Rational('3.141592653589793').limit_denominator(10)\n",
      " |      22/7\n",
      " |      >>> Rational('3.141592653589793').limit_denominator(100)\n",
      " |      311/99\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Static methods defined here:\n",
      " |  \n",
      " |  __new__(cls, p, q=None, gcd=None)\n",
      " |      Create and return a new object.  See help(type) for accurate signature.\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Readonly properties defined here:\n",
      " |  \n",
      " |  __sympy__\n",
      " |  \n",
      " |  denominator\n",
      " |  \n",
      " |  numerator\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Data descriptors defined here:\n",
      " |  \n",
      " |  p\n",
      " |  \n",
      " |  q\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Data and other attributes defined here:\n",
      " |  \n",
      " |  default_assumptions = {'commutative': True, 'rational': True, 'transce...\n",
      " |  \n",
      " |  is_Rational = True\n",
      " |  \n",
      " |  is_algebraic = True\n",
      " |  \n",
      " |  is_commutative = True\n",
      " |  \n",
      " |  is_complex = True\n",
      " |  \n",
      " |  is_composite = False\n",
      " |  \n",
      " |  is_even = False\n",
      " |  \n",
      " |  is_extended_nonzero = True\n",
      " |  \n",
      " |  is_extended_real = True\n",
      " |  \n",
      " |  is_finite = True\n",
      " |  \n",
      " |  is_hermitian = True\n",
      " |  \n",
      " |  is_imaginary = False\n",
      " |  \n",
      " |  is_infinite = False\n",
      " |  \n",
      " |  is_integer = False\n",
      " |  \n",
      " |  is_irrational = False\n",
      " |  \n",
      " |  is_noninteger = True\n",
      " |  \n",
      " |  is_nonzero = True\n",
      " |  \n",
      " |  is_number = True\n",
      " |  \n",
      " |  is_odd = False\n",
      " |  \n",
      " |  is_prime = False\n",
      " |  \n",
      " |  is_rational = True\n",
      " |  \n",
      " |  is_real = True\n",
      " |  \n",
      " |  is_transcendental = False\n",
      " |  \n",
      " |  is_zero = False\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Methods inherited from Number:\n",
      " |  \n",
      " |  __divmod__(self, other)\n",
      " |  \n",
      " |  __float__(self)\n",
      " |  \n",
      " |  __rdivmod__(self, other)\n",
      " |  \n",
      " |  as_coeff_add(self, *deps)\n",
      " |      Return the tuple (c, args) where self is written as an Add, ``a``.\n",
      " |      \n",
      " |      c should be a Rational added to any terms of the Add that are\n",
      " |      independent of deps.\n",
      " |      \n",
      " |      args should be a tuple of all other terms of ``a``; args is empty\n",
      " |      if self is a Number or if self is independent of deps (when given).\n",
      " |      \n",
      " |      This should be used when you don't know if self is an Add or not but\n",
      " |      you want to treat self as an Add or if you want to process the\n",
      " |      individual arguments of the tail of self as an Add.\n",
      " |      \n",
      " |      - if you know self is an Add and want only the head, use self.args[0];\n",
      " |      - if you don't want to process the arguments of the tail but need the\n",
      " |        tail then use self.as_two_terms() which gives the head and tail.\n",
      " |      - if you want to split self into an independent and dependent parts\n",
      " |        use ``self.as_independent(*deps)``\n",
      " |      \n",
      " |      >>> from sympy import S\n",
      " |      >>> from sympy.abc import x, y\n",
      " |      >>> (S(3)).as_coeff_add()\n",
      " |      (3, ())\n",
      " |      >>> (3 + x).as_coeff_add()\n",
      " |      (3, (x,))\n",
      " |      >>> (3 + x + y).as_coeff_add(x)\n",
      " |      (y + 3, (x,))\n",
      " |      >>> (3 + y).as_coeff_add(x)\n",
      " |      (y + 3, ())\n",
      " |  \n",
      " |  as_coeff_mul(self, *deps, rational=True, **kwargs)\n",
      " |      Return the tuple (c, args) where self is written as a Mul, ``m``.\n",
      " |      \n",
      " |      c should be a Rational multiplied by any factors of the Mul that are\n",
      " |      independent of deps.\n",
      " |      \n",
      " |      args should be a tuple of all other factors of m; args is empty\n",
      " |      if self is a Number or if self is independent of deps (when given).\n",
      " |      \n",
      " |      This should be used when you don't know if self is a Mul or not but\n",
      " |      you want to treat self as a Mul or if you want to process the\n",
      " |      individual arguments of the tail of self as a Mul.\n",
      " |      \n",
      " |      - if you know self is a Mul and want only the head, use self.args[0];\n",
      " |      - if you don't want to process the arguments of the tail but need the\n",
      " |        tail then use self.as_two_terms() which gives the head and tail;\n",
      " |      - if you want to split self into an independent and dependent parts\n",
      " |        use ``self.as_independent(*deps)``\n",
      " |      \n",
      " |      >>> from sympy import S\n",
      " |      >>> from sympy.abc import x, y\n",
      " |      >>> (S(3)).as_coeff_mul()\n",
      " |      (3, ())\n",
      " |      >>> (3*x*y).as_coeff_mul()\n",
      " |      (3, (x, y))\n",
      " |      >>> (3*x*y).as_coeff_mul(x)\n",
      " |      (3*y, (x,))\n",
      " |      >>> (3*y).as_coeff_mul(x)\n",
      " |      (3*y, ())\n",
      " |  \n",
      " |  cofactors(self, other)\n",
      " |      Compute GCD and cofactors of `self` and `other`.\n",
      " |  \n",
      " |  invert(self, other, *gens, **args)\n",
      " |      Return the multiplicative inverse of ``self`` mod ``g``\n",
      " |      where ``self`` (and ``g``) may be symbolic expressions).\n",
      " |      \n",
      " |      See Also\n",
      " |      ========\n",
      " |      sympy.core.numbers.mod_inverse, sympy.polys.polytools.invert\n",
      " |  \n",
      " |  is_constant(self, *wrt, **flags)\n",
      " |      Return True if self is constant, False if not, or None if\n",
      " |      the constancy could not be determined conclusively.\n",
      " |      \n",
      " |      Explanation\n",
      " |      ===========\n",
      " |      \n",
      " |      If an expression has no free symbols then it is a constant. If\n",
      " |      there are free symbols it is possible that the expression is a\n",
      " |      constant, perhaps (but not necessarily) zero. To test such\n",
      " |      expressions, a few strategies are tried:\n",
      " |      \n",
      " |      1) numerical evaluation at two random points. If two such evaluations\n",
      " |      give two different values and the values have a precision greater than\n",
      " |      1 then self is not constant. If the evaluations agree or could not be\n",
      " |      obtained with any precision, no decision is made. The numerical testing\n",
      " |      is done only if ``wrt`` is different than the free symbols.\n",
      " |      \n",
      " |      2) differentiation with respect to variables in 'wrt' (or all free\n",
      " |      symbols if omitted) to see if the expression is constant or not. This\n",
      " |      will not always lead to an expression that is zero even though an\n",
      " |      expression is constant (see added test in test_expr.py). If\n",
      " |      all derivatives are zero then self is constant with respect to the\n",
      " |      given symbols.\n",
      " |      \n",
      " |      3) finding out zeros of denominator expression with free_symbols.\n",
      " |      It won't be constant if there are zeros. It gives more negative\n",
      " |      answers for expression that are not constant.\n",
      " |      \n",
      " |      If neither evaluation nor differentiation can prove the expression is\n",
      " |      constant, None is returned unless two numerical values happened to be\n",
      " |      the same and the flag ``failing_number`` is True -- in that case the\n",
      " |      numerical value will be returned.\n",
      " |      \n",
      " |      If flag simplify=False is passed, self will not be simplified;\n",
      " |      the default is True since self should be simplified before testing.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy import cos, sin, Sum, S, pi\n",
      " |      >>> from sympy.abc import a, n, x, y\n",
      " |      >>> x.is_constant()\n",
      " |      False\n",
      " |      >>> S(2).is_constant()\n",
      " |      True\n",
      " |      >>> Sum(x, (x, 1, 10)).is_constant()\n",
      " |      True\n",
      " |      >>> Sum(x, (x, 1, n)).is_constant()\n",
      " |      False\n",
      " |      >>> Sum(x, (x, 1, n)).is_constant(y)\n",
      " |      True\n",
      " |      >>> Sum(x, (x, 1, n)).is_constant(n)\n",
      " |      False\n",
      " |      >>> Sum(x, (x, 1, n)).is_constant(x)\n",
      " |      True\n",
      " |      >>> eq = a*cos(x)**2 + a*sin(x)**2 - a\n",
      " |      >>> eq.is_constant()\n",
      " |      True\n",
      " |      >>> eq.subs({x: pi, a: 2}) == eq.subs({x: pi, a: 3}) == 0\n",
      " |      True\n",
      " |      \n",
      " |      >>> (0**x).is_constant()\n",
      " |      False\n",
      " |      >>> x.is_constant()\n",
      " |      False\n",
      " |      >>> (x**x).is_constant()\n",
      " |      False\n",
      " |      >>> one = cos(x)**2 + sin(x)**2\n",
      " |      >>> one.is_constant()\n",
      " |      True\n",
      " |      >>> ((one - 1)**(x + 1)).is_constant() in (True, False) # could be 0 or 1\n",
      " |      True\n",
      " |  \n",
      " |  sort_key(self, order=None)\n",
      " |      Return a sort key.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy.core import S, I\n",
      " |      \n",
      " |      >>> sorted([S(1)/2, I, -I], key=lambda x: x.sort_key())\n",
      " |      [1/2, -I, I]\n",
      " |      \n",
      " |      >>> S(\"[x, 1/x, 1/x**2, x**2, x**(1/2), x**(1/4), x**(3/2)]\")\n",
      " |      [x, 1/x, x**(-2), x**2, sqrt(x), x**(1/4), x**(3/2)]\n",
      " |      >>> sorted(_, key=lambda x: x.sort_key())\n",
      " |      [x**(-2), 1/x, x**(1/4), sqrt(x), x, x**(3/2), x**2]\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Class methods inherited from Number:\n",
      " |  \n",
      " |  class_key() from sympy.core.assumptions.ManagedProperties\n",
      " |      Nice order of classes.\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Data and other attributes inherited from Number:\n",
      " |  \n",
      " |  is_Number = True\n",
      " |  \n",
      " |  kind = NumberKind\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Readonly properties inherited from sympy.core.expr.AtomicExpr:\n",
      " |  \n",
      " |  expr_free_symbols\n",
      " |      Like ``free_symbols``, but returns the free symbols only if\n",
      " |      they are contained in an expression node.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy.utilities.exceptions import SymPyDeprecationWarning\n",
      " |      >>> import warnings\n",
      " |      >>> warnings.simplefilter(\"ignore\", SymPyDeprecationWarning)\n",
      " |      >>> from sympy.abc import x, y\n",
      " |      >>> (x + y).expr_free_symbols\n",
      " |      {x, y}\n",
      " |      \n",
      " |      If the expression is contained in a non-expression object, don't return\n",
      " |      the free symbols. Compare:\n",
      " |      \n",
      " |      >>> from sympy import Tuple\n",
      " |      >>> t = Tuple(x + y)\n",
      " |      >>> t.expr_free_symbols\n",
      " |      set()\n",
      " |      >>> t.free_symbols\n",
      " |      {x, y}\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Data and other attributes inherited from sympy.core.expr.AtomicExpr:\n",
      " |  \n",
      " |  is_Atom = True\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Methods inherited from sympy.core.basic.Atom:\n",
      " |  \n",
      " |  doit(self, **hints)\n",
      " |      Evaluate objects that are not evaluated by default like limits,\n",
      " |      integrals, sums and products. All objects of this kind will be\n",
      " |      evaluated recursively, unless some species were excluded via 'hints'\n",
      " |      or unless the 'deep' hint was set to 'False'.\n",
      " |      \n",
      " |      >>> from sympy import Integral\n",
      " |      >>> from sympy.abc import x\n",
      " |      \n",
      " |      >>> 2*Integral(x, x)\n",
      " |      2*Integral(x, x)\n",
      " |      \n",
      " |      >>> (2*Integral(x, x)).doit()\n",
      " |      x**2\n",
      " |      \n",
      " |      >>> (2*Integral(x, x)).doit(deep=False)\n",
      " |      2*Integral(x, x)\n",
      " |  \n",
      " |  matches(self, expr, repl_dict={}, old=False)\n",
      " |      Helper method for match() that looks for a match between Wild symbols\n",
      " |      in self and expressions in expr.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy import symbols, Wild, Basic\n",
      " |      >>> a, b, c = symbols('a b c')\n",
      " |      >>> x = Wild('x')\n",
      " |      >>> Basic(a + x, x).matches(Basic(a + b, c)) is None\n",
      " |      True\n",
      " |      >>> Basic(a + x, x).matches(Basic(a + b + c, b + c))\n",
      " |      {x_: b + c}\n",
      " |  \n",
      " |  xreplace(self, rule, hack2=False)\n",
      " |      Replace occurrences of objects within the expression.\n",
      " |      \n",
      " |      Parameters\n",
      " |      ==========\n",
      " |      \n",
      " |      rule : dict-like\n",
      " |          Expresses a replacement rule\n",
      " |      \n",
      " |      Returns\n",
      " |      =======\n",
      " |      \n",
      " |      xreplace : the result of the replacement\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy import symbols, pi, exp\n",
      " |      >>> x, y, z = symbols('x y z')\n",
      " |      >>> (1 + x*y).xreplace({x: pi})\n",
      " |      pi*y + 1\n",
      " |      >>> (1 + x*y).xreplace({x: pi, y: 2})\n",
      " |      1 + 2*pi\n",
      " |      \n",
      " |      Replacements occur only if an entire node in the expression tree is\n",
      " |      matched:\n",
      " |      \n",
      " |      >>> (x*y + z).xreplace({x*y: pi})\n",
      " |      z + pi\n",
      " |      >>> (x*y*z).xreplace({x*y: pi})\n",
      " |      x*y*z\n",
      " |      >>> (2*x).xreplace({2*x: y, x: z})\n",
      " |      y\n",
      " |      >>> (2*2*x).xreplace({2*x: y, x: z})\n",
      " |      4*z\n",
      " |      >>> (x + y + 2).xreplace({x + y: 2})\n",
      " |      x + y + 2\n",
      " |      >>> (x + 2 + exp(x + 2)).xreplace({x + 2: y})\n",
      " |      x + exp(y) + 2\n",
      " |      \n",
      " |      xreplace doesn't differentiate between free and bound symbols. In the\n",
      " |      following, subs(x, y) would not change x since it is a bound symbol,\n",
      " |      but xreplace does:\n",
      " |      \n",
      " |      >>> from sympy import Integral\n",
      " |      >>> Integral(x, (x, 1, 2*x)).xreplace({x: y})\n",
      " |      Integral(y, (y, 1, 2*y))\n",
      " |      \n",
      " |      Trying to replace x with an expression raises an error:\n",
      " |      \n",
      " |      >>> Integral(x, (x, 1, 2*x)).xreplace({x: 2*y}) # doctest: +SKIP\n",
      " |      ValueError: Invalid limits given: ((2*y, 1, 4*y),)\n",
      " |      \n",
      " |      See Also\n",
      " |      ========\n",
      " |      replace: replacement capable of doing wildcard-like matching,\n",
      " |               parsing of match, and conditional replacements\n",
      " |      subs: substitution of subexpressions as defined by the objects\n",
      " |            themselves.\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Methods inherited from sympy.core.expr.Expr:\n",
      " |  \n",
      " |  __complex__(self)\n",
      " |  \n",
      " |  __floordiv__(self, other)\n",
      " |  \n",
      " |  __pos__(self)\n",
      " |  \n",
      " |  __pow__(self, other, mod=None)\n",
      " |  \n",
      " |  __rfloordiv__(self, other)\n",
      " |  \n",
      " |  __round__ = round(self, n=None)\n",
      " |  \n",
      " |  __rpow__(self, other)\n",
      " |  \n",
      " |  __trunc__(self)\n",
      " |  \n",
      " |  adjoint(self)\n",
      " |  \n",
      " |  apart(self, x=None, **args)\n",
      " |      See the apart function in sympy.polys\n",
      " |  \n",
      " |  args_cnc(self, cset=False, warn=True, split_1=True)\n",
      " |      Return [commutative factors, non-commutative factors] of self.\n",
      " |      \n",
      " |      Explanation\n",
      " |      ===========\n",
      " |      \n",
      " |      self is treated as a Mul and the ordering of the factors is maintained.\n",
      " |      If ``cset`` is True the commutative factors will be returned in a set.\n",
      " |      If there were repeated factors (as may happen with an unevaluated Mul)\n",
      " |      then an error will be raised unless it is explicitly suppressed by\n",
      " |      setting ``warn`` to False.\n",
      " |      \n",
      " |      Note: -1 is always separated from a Number unless split_1 is False.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy import symbols, oo\n",
      " |      >>> A, B = symbols('A B', commutative=0)\n",
      " |      >>> x, y = symbols('x y')\n",
      " |      >>> (-2*x*y).args_cnc()\n",
      " |      [[-1, 2, x, y], []]\n",
      " |      >>> (-2.5*x).args_cnc()\n",
      " |      [[-1, 2.5, x], []]\n",
      " |      >>> (-2*x*A*B*y).args_cnc()\n",
      " |      [[-1, 2, x, y], [A, B]]\n",
      " |      >>> (-2*x*A*B*y).args_cnc(split_1=False)\n",
      " |      [[-2, x, y], [A, B]]\n",
      " |      >>> (-2*x*y).args_cnc(cset=True)\n",
      " |      [{-1, 2, x, y}, []]\n",
      " |      \n",
      " |      The arg is always treated as a Mul:\n",
      " |      \n",
      " |      >>> (-2 + x + A).args_cnc()\n",
      " |      [[], [x - 2 + A]]\n",
      " |      >>> (-oo).args_cnc() # -oo is a singleton\n",
      " |      [[-1, oo], []]\n",
      " |  \n",
      " |  as_base_exp(self)\n",
      " |  \n",
      " |  as_coeff_exponent(self, x)\n",
      " |      ``c*x**e -> c,e`` where x can be any symbolic expression.\n",
      " |  \n",
      " |  as_coefficient(self, expr)\n",
      " |      Extracts symbolic coefficient at the given expression. In\n",
      " |      other words, this functions separates 'self' into the product\n",
      " |      of 'expr' and 'expr'-free coefficient. If such separation\n",
      " |      is not possible it will return None.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy import E, pi, sin, I, Poly\n",
      " |      >>> from sympy.abc import x\n",
      " |      \n",
      " |      >>> E.as_coefficient(E)\n",
      " |      1\n",
      " |      >>> (2*E).as_coefficient(E)\n",
      " |      2\n",
      " |      >>> (2*sin(E)*E).as_coefficient(E)\n",
      " |      \n",
      " |      Two terms have E in them so a sum is returned. (If one were\n",
      " |      desiring the coefficient of the term exactly matching E then\n",
      " |      the constant from the returned expression could be selected.\n",
      " |      Or, for greater precision, a method of Poly can be used to\n",
      " |      indicate the desired term from which the coefficient is\n",
      " |      desired.)\n",
      " |      \n",
      " |      >>> (2*E + x*E).as_coefficient(E)\n",
      " |      x + 2\n",
      " |      >>> _.args[0]  # just want the exact match\n",
      " |      2\n",
      " |      >>> p = Poly(2*E + x*E); p\n",
      " |      Poly(x*E + 2*E, x, E, domain='ZZ')\n",
      " |      >>> p.coeff_monomial(E)\n",
      " |      2\n",
      " |      >>> p.nth(0, 1)\n",
      " |      2\n",
      " |      \n",
      " |      Since the following cannot be written as a product containing\n",
      " |      E as a factor, None is returned. (If the coefficient ``2*x`` is\n",
      " |      desired then the ``coeff`` method should be used.)\n",
      " |      \n",
      " |      >>> (2*E*x + x).as_coefficient(E)\n",
      " |      >>> (2*E*x + x).coeff(E)\n",
      " |      2*x\n",
      " |      \n",
      " |      >>> (E*(x + 1) + x).as_coefficient(E)\n",
      " |      \n",
      " |      >>> (2*pi*I).as_coefficient(pi*I)\n",
      " |      2\n",
      " |      >>> (2*I).as_coefficient(pi*I)\n",
      " |      \n",
      " |      See Also\n",
      " |      ========\n",
      " |      \n",
      " |      coeff: return sum of terms have a given factor\n",
      " |      as_coeff_Add: separate the additive constant from an expression\n",
      " |      as_coeff_Mul: separate the multiplicative constant from an expression\n",
      " |      as_independent: separate x-dependent terms/factors from others\n",
      " |      sympy.polys.polytools.Poly.coeff_monomial: efficiently find the single coefficient of a monomial in Poly\n",
      " |      sympy.polys.polytools.Poly.nth: like coeff_monomial but powers of monomial terms are used\n",
      " |  \n",
      " |  as_coefficients_dict(self)\n",
      " |      Return a dictionary mapping terms to their Rational coefficient.\n",
      " |      Since the dictionary is a defaultdict, inquiries about terms which\n",
      " |      were not present will return a coefficient of 0. If an expression is\n",
      " |      not an Add it is considered to have a single term.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy.abc import a, x\n",
      " |      >>> (3*x + a*x + 4).as_coefficients_dict()\n",
      " |      {1: 4, x: 3, a*x: 1}\n",
      " |      >>> _[a]\n",
      " |      0\n",
      " |      >>> (3*a*x).as_coefficients_dict()\n",
      " |      {a*x: 3}\n",
      " |  \n",
      " |  as_expr(self, *gens)\n",
      " |      Convert a polynomial to a SymPy expression.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy import sin\n",
      " |      >>> from sympy.abc import x, y\n",
      " |      \n",
      " |      >>> f = (x**2 + x*y).as_poly(x, y)\n",
      " |      >>> f.as_expr()\n",
      " |      x**2 + x*y\n",
      " |      \n",
      " |      >>> sin(x).as_expr()\n",
      " |      sin(x)\n",
      " |  \n",
      " |  as_independent(self, *deps, **hint)\n",
      " |      A mostly naive separation of a Mul or Add into arguments that are not\n",
      " |      are dependent on deps. To obtain as complete a separation of variables\n",
      " |      as possible, use a separation method first, e.g.:\n",
      " |      \n",
      " |      * separatevars() to change Mul, Add and Pow (including exp) into Mul\n",
      " |      * .expand(mul=True) to change Add or Mul into Add\n",
      " |      * .expand(log=True) to change log expr into an Add\n",
      " |      \n",
      " |      The only non-naive thing that is done here is to respect noncommutative\n",
      " |      ordering of variables and to always return (0, 0) for `self` of zero\n",
      " |      regardless of hints.\n",
      " |      \n",
      " |      For nonzero `self`, the returned tuple (i, d) has the\n",
      " |      following interpretation:\n",
      " |      \n",
      " |      * i will has no variable that appears in deps\n",
      " |      * d will either have terms that contain variables that are in deps, or\n",
      " |        be equal to 0 (when self is an Add) or 1 (when self is a Mul)\n",
      " |      * if self is an Add then self = i + d\n",
      " |      * if self is a Mul then self = i*d\n",
      " |      * otherwise (self, S.One) or (S.One, self) is returned.\n",
      " |      \n",
      " |      To force the expression to be treated as an Add, use the hint as_Add=True\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      -- self is an Add\n",
      " |      \n",
      " |      >>> from sympy import sin, cos, exp\n",
      " |      >>> from sympy.abc import x, y, z\n",
      " |      \n",
      " |      >>> (x + x*y).as_independent(x)\n",
      " |      (0, x*y + x)\n",
      " |      >>> (x + x*y).as_independent(y)\n",
      " |      (x, x*y)\n",
      " |      >>> (2*x*sin(x) + y + x + z).as_independent(x)\n",
      " |      (y + z, 2*x*sin(x) + x)\n",
      " |      >>> (2*x*sin(x) + y + x + z).as_independent(x, y)\n",
      " |      (z, 2*x*sin(x) + x + y)\n",
      " |      \n",
      " |      -- self is a Mul\n",
      " |      \n",
      " |      >>> (x*sin(x)*cos(y)).as_independent(x)\n",
      " |      (cos(y), x*sin(x))\n",
      " |      \n",
      " |      non-commutative terms cannot always be separated out when self is a Mul\n",
      " |      \n",
      " |      >>> from sympy import symbols\n",
      " |      >>> n1, n2, n3 = symbols('n1 n2 n3', commutative=False)\n",
      " |      >>> (n1 + n1*n2).as_independent(n2)\n",
      " |      (n1, n1*n2)\n",
      " |      >>> (n2*n1 + n1*n2).as_independent(n2)\n",
      " |      (0, n1*n2 + n2*n1)\n",
      " |      >>> (n1*n2*n3).as_independent(n1)\n",
      " |      (1, n1*n2*n3)\n",
      " |      >>> (n1*n2*n3).as_independent(n2)\n",
      " |      (n1, n2*n3)\n",
      " |      >>> ((x-n1)*(x-y)).as_independent(x)\n",
      " |      (1, (x - y)*(x - n1))\n",
      " |      \n",
      " |      -- self is anything else:\n",
      " |      \n",
      " |      >>> (sin(x)).as_independent(x)\n",
      " |      (1, sin(x))\n",
      " |      >>> (sin(x)).as_independent(y)\n",
      " |      (sin(x), 1)\n",
      " |      >>> exp(x+y).as_independent(x)\n",
      " |      (1, exp(x + y))\n",
      " |      \n",
      " |      -- force self to be treated as an Add:\n",
      " |      \n",
      " |      >>> (3*x).as_independent(x, as_Add=True)\n",
      " |      (0, 3*x)\n",
      " |      \n",
      " |      -- force self to be treated as a Mul:\n",
      " |      \n",
      " |      >>> (3+x).as_independent(x, as_Add=False)\n",
      " |      (1, x + 3)\n",
      " |      >>> (-3+x).as_independent(x, as_Add=False)\n",
      " |      (1, x - 3)\n",
      " |      \n",
      " |      Note how the below differs from the above in making the\n",
      " |      constant on the dep term positive.\n",
      " |      \n",
      " |      >>> (y*(-3+x)).as_independent(x)\n",
      " |      (y, x - 3)\n",
      " |      \n",
      " |      -- use .as_independent() for true independence testing instead\n",
      " |         of .has(). The former considers only symbols in the free\n",
      " |         symbols while the latter considers all symbols\n",
      " |      \n",
      " |      >>> from sympy import Integral\n",
      " |      >>> I = Integral(x, (x, 1, 2))\n",
      " |      >>> I.has(x)\n",
      " |      True\n",
      " |      >>> x in I.free_symbols\n",
      " |      False\n",
      " |      >>> I.as_independent(x) == (I, 1)\n",
      " |      True\n",
      " |      >>> (I + x).as_independent(x) == (I, x)\n",
      " |      True\n",
      " |      \n",
      " |      Note: when trying to get independent terms, a separation method\n",
      " |      might need to be used first. In this case, it is important to keep\n",
      " |      track of what you send to this routine so you know how to interpret\n",
      " |      the returned values\n",
      " |      \n",
      " |      >>> from sympy import separatevars, log\n",
      " |      >>> separatevars(exp(x+y)).as_independent(x)\n",
      " |      (exp(y), exp(x))\n",
      " |      >>> (x + x*y).as_independent(y)\n",
      " |      (x, x*y)\n",
      " |      >>> separatevars(x + x*y).as_independent(y)\n",
      " |      (x, y + 1)\n",
      " |      >>> (x*(1 + y)).as_independent(y)\n",
      " |      (x, y + 1)\n",
      " |      >>> (x*(1 + y)).expand(mul=True).as_independent(y)\n",
      " |      (x, x*y)\n",
      " |      >>> a, b=symbols('a b', positive=True)\n",
      " |      >>> (log(a*b).expand(log=True)).as_independent(b)\n",
      " |      (log(a), log(b))\n",
      " |      \n",
      " |      See Also\n",
      " |      ========\n",
      " |      .separatevars(), .expand(log=True), sympy.core.add.Add.as_two_terms(),\n",
      " |      sympy.core.mul.Mul.as_two_terms(), .as_coeff_add(), .as_coeff_mul()\n",
      " |  \n",
      " |  as_leading_term(self, *symbols, logx=None, cdir=0)\n",
      " |      Returns the leading (nonzero) term of the series expansion of self.\n",
      " |      \n",
      " |      The _eval_as_leading_term routines are used to do this, and they must\n",
      " |      always return a non-zero value.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy.abc import x\n",
      " |      >>> (1 + x + x**2).as_leading_term(x)\n",
      " |      1\n",
      " |      >>> (1/x**2 + x + x**2).as_leading_term(x)\n",
      " |      x**(-2)\n",
      " |  \n",
      " |  as_ordered_factors(self, order=None)\n",
      " |      Return list of ordered factors (if Mul) else [self].\n",
      " |  \n",
      " |  as_ordered_terms(self, order=None, data=False)\n",
      " |      Transform an expression to an ordered list of terms.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy import sin, cos\n",
      " |      >>> from sympy.abc import x\n",
      " |      \n",
      " |      >>> (sin(x)**2*cos(x) + sin(x)**2 + 1).as_ordered_terms()\n",
      " |      [sin(x)**2*cos(x), sin(x)**2, 1]\n",
      " |  \n",
      " |  as_poly(self, *gens, **args)\n",
      " |      Converts ``self`` to a polynomial or returns ``None``.\n",
      " |      \n",
      " |      Explanation\n",
      " |      ===========\n",
      " |      \n",
      " |      >>> from sympy import sin\n",
      " |      >>> from sympy.abc import x, y\n",
      " |      \n",
      " |      >>> print((x**2 + x*y).as_poly())\n",
      " |      Poly(x**2 + x*y, x, y, domain='ZZ')\n",
      " |      \n",
      " |      >>> print((x**2 + x*y).as_poly(x, y))\n",
      " |      Poly(x**2 + x*y, x, y, domain='ZZ')\n",
      " |      \n",
      " |      >>> print((x**2 + sin(y)).as_poly(x, y))\n",
      " |      None\n",
      " |  \n",
      " |  as_powers_dict(self)\n",
      " |      Return self as a dictionary of factors with each factor being\n",
      " |      treated as a power. The keys are the bases of the factors and the\n",
      " |      values, the corresponding exponents. The resulting dictionary should\n",
      " |      be used with caution if the expression is a Mul and contains non-\n",
      " |      commutative factors since the order that they appeared will be lost in\n",
      " |      the dictionary.\n",
      " |      \n",
      " |      See Also\n",
      " |      ========\n",
      " |      as_ordered_factors: An alternative for noncommutative applications,\n",
      " |                          returning an ordered list of factors.\n",
      " |      args_cnc: Similar to as_ordered_factors, but guarantees separation\n",
      " |                of commutative and noncommutative factors.\n",
      " |  \n",
      " |  as_real_imag(self, deep=True, **hints)\n",
      " |      Performs complex expansion on 'self' and returns a tuple\n",
      " |      containing collected both real and imaginary parts. This\n",
      " |      method can't be confused with re() and im() functions,\n",
      " |      which does not perform complex expansion at evaluation.\n",
      " |      \n",
      " |      However it is possible to expand both re() and im()\n",
      " |      functions and get exactly the same results as with\n",
      " |      a single call to this function.\n",
      " |      \n",
      " |      >>> from sympy import symbols, I\n",
      " |      \n",
      " |      >>> x, y = symbols('x,y', real=True)\n",
      " |      \n",
      " |      >>> (x + y*I).as_real_imag()\n",
      " |      (x, y)\n",
      " |      \n",
      " |      >>> from sympy.abc import z, w\n",
      " |      \n",
      " |      >>> (z + w*I).as_real_imag()\n",
      " |      (re(z) - im(w), re(w) + im(z))\n",
      " |  \n",
      " |  as_terms(self)\n",
      " |      Transform an expression to a list of terms.\n",
      " |  \n",
      " |  aseries(self, x=None, n=6, bound=0, hir=False)\n",
      " |      Asymptotic Series expansion of self.\n",
      " |      This is equivalent to ``self.series(x, oo, n)``.\n",
      " |      \n",
      " |      Parameters\n",
      " |      ==========\n",
      " |      \n",
      " |      self : Expression\n",
      " |             The expression whose series is to be expanded.\n",
      " |      \n",
      " |      x : Symbol\n",
      " |          It is the variable of the expression to be calculated.\n",
      " |      \n",
      " |      n : Value\n",
      " |          The number of terms upto which the series is to be expanded.\n",
      " |      \n",
      " |      hir : Boolean\n",
      " |            Set this parameter to be True to produce hierarchical series.\n",
      " |            It stops the recursion at an early level and may provide nicer\n",
      " |            and more useful results.\n",
      " |      \n",
      " |      bound : Value, Integer\n",
      " |              Use the ``bound`` parameter to give limit on rewriting\n",
      " |              coefficients in its normalised form.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy import sin, exp\n",
      " |      >>> from sympy.abc import x\n",
      " |      \n",
      " |      >>> e = sin(1/x + exp(-x)) - sin(1/x)\n",
      " |      \n",
      " |      >>> e.aseries(x)\n",
      " |      (1/(24*x**4) - 1/(2*x**2) + 1 + O(x**(-6), (x, oo)))*exp(-x)\n",
      " |      \n",
      " |      >>> e.aseries(x, n=3, hir=True)\n",
      " |      -exp(-2*x)*sin(1/x)/2 + exp(-x)*cos(1/x) + O(exp(-3*x), (x, oo))\n",
      " |      \n",
      " |      >>> e = exp(exp(x)/(1 - 1/x))\n",
      " |      \n",
      " |      >>> e.aseries(x)\n",
      " |      exp(exp(x)/(1 - 1/x))\n",
      " |      \n",
      " |      >>> e.aseries(x, bound=3) # doctest: +SKIP\n",
      " |      exp(exp(x)/x**2)*exp(exp(x)/x)*exp(-exp(x) + exp(x)/(1 - 1/x) - exp(x)/x - exp(x)/x**2)*exp(exp(x))\n",
      " |      \n",
      " |      Returns\n",
      " |      =======\n",
      " |      \n",
      " |      Expr\n",
      " |          Asymptotic series expansion of the expression.\n",
      " |      \n",
      " |      Notes\n",
      " |      =====\n",
      " |      \n",
      " |      This algorithm is directly induced from the limit computational algorithm provided by Gruntz.\n",
      " |      It majorly uses the mrv and rewrite sub-routines. The overall idea of this algorithm is first\n",
      " |      to look for the most rapidly varying subexpression w of a given expression f and then expands f\n",
      " |      in a series in w. Then same thing is recursively done on the leading coefficient\n",
      " |      till we get constant coefficients.\n",
      " |      \n",
      " |      If the most rapidly varying subexpression of a given expression f is f itself,\n",
      " |      the algorithm tries to find a normalised representation of the mrv set and rewrites f\n",
      " |      using this normalised representation.\n",
      " |      \n",
      " |      If the expansion contains an order term, it will be either ``O(x ** (-n))`` or ``O(w ** (-n))``\n",
      " |      where ``w`` belongs to the most rapidly varying expression of ``self``.\n",
      " |      \n",
      " |      References\n",
      " |      ==========\n",
      " |      \n",
      " |      .. [1] A New Algorithm for Computing Asymptotic Series - Dominik Gruntz\n",
      " |      .. [2] Gruntz thesis - p90\n",
      " |      .. [3] http://en.wikipedia.org/wiki/Asymptotic_expansion\n",
      " |      \n",
      " |      See Also\n",
      " |      ========\n",
      " |      \n",
      " |      Expr.aseries: See the docstring of this function for complete details of this wrapper.\n",
      " |  \n",
      " |  cancel(self, *gens, **args)\n",
      " |      See the cancel function in sympy.polys\n",
      " |  \n",
      " |  coeff(self, x, n=1, right=False)\n",
      " |      Returns the coefficient from the term(s) containing ``x**n``. If ``n``\n",
      " |      is zero then all terms independent of ``x`` will be returned.\n",
      " |      \n",
      " |      Explanation\n",
      " |      ===========\n",
      " |      \n",
      " |      When ``x`` is noncommutative, the coefficient to the left (default) or\n",
      " |      right of ``x`` can be returned. The keyword 'right' is ignored when\n",
      " |      ``x`` is commutative.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy import symbols\n",
      " |      >>> from sympy.abc import x, y, z\n",
      " |      \n",
      " |      You can select terms that have an explicit negative in front of them:\n",
      " |      \n",
      " |      >>> (-x + 2*y).coeff(-1)\n",
      " |      x\n",
      " |      >>> (x - 2*y).coeff(-1)\n",
      " |      2*y\n",
      " |      \n",
      " |      You can select terms with no Rational coefficient:\n",
      " |      \n",
      " |      >>> (x + 2*y).coeff(1)\n",
      " |      x\n",
      " |      >>> (3 + 2*x + 4*x**2).coeff(1)\n",
      " |      0\n",
      " |      \n",
      " |      You can select terms independent of x by making n=0; in this case\n",
      " |      expr.as_independent(x)[0] is returned (and 0 will be returned instead\n",
      " |      of None):\n",
      " |      \n",
      " |      >>> (3 + 2*x + 4*x**2).coeff(x, 0)\n",
      " |      3\n",
      " |      >>> eq = ((x + 1)**3).expand() + 1\n",
      " |      >>> eq\n",
      " |      x**3 + 3*x**2 + 3*x + 2\n",
      " |      >>> [eq.coeff(x, i) for i in reversed(range(4))]\n",
      " |      [1, 3, 3, 2]\n",
      " |      >>> eq -= 2\n",
      " |      >>> [eq.coeff(x, i) for i in reversed(range(4))]\n",
      " |      [1, 3, 3, 0]\n",
      " |      \n",
      " |      You can select terms that have a numerical term in front of them:\n",
      " |      \n",
      " |      >>> (-x - 2*y).coeff(2)\n",
      " |      -y\n",
      " |      >>> from sympy import sqrt\n",
      " |      >>> (x + sqrt(2)*x).coeff(sqrt(2))\n",
      " |      x\n",
      " |      \n",
      " |      The matching is exact:\n",
      " |      \n",
      " |      >>> (3 + 2*x + 4*x**2).coeff(x)\n",
      " |      2\n",
      " |      >>> (3 + 2*x + 4*x**2).coeff(x**2)\n",
      " |      4\n",
      " |      >>> (3 + 2*x + 4*x**2).coeff(x**3)\n",
      " |      0\n",
      " |      >>> (z*(x + y)**2).coeff((x + y)**2)\n",
      " |      z\n",
      " |      >>> (z*(x + y)**2).coeff(x + y)\n",
      " |      0\n",
      " |      \n",
      " |      In addition, no factoring is done, so 1 + z*(1 + y) is not obtained\n",
      " |      from the following:\n",
      " |      \n",
      " |      >>> (x + z*(x + x*y)).coeff(x)\n",
      " |      1\n",
      " |      \n",
      " |      If such factoring is desired, factor_terms can be used first:\n",
      " |      \n",
      " |      >>> from sympy import factor_terms\n",
      " |      >>> factor_terms(x + z*(x + x*y)).coeff(x)\n",
      " |      z*(y + 1) + 1\n",
      " |      \n",
      " |      >>> n, m, o = symbols('n m o', commutative=False)\n",
      " |      >>> n.coeff(n)\n",
      " |      1\n",
      " |      >>> (3*n).coeff(n)\n",
      " |      3\n",
      " |      >>> (n*m + m*n*m).coeff(n) # = (1 + m)*n*m\n",
      " |      1 + m\n",
      " |      >>> (n*m + m*n*m).coeff(n, right=True) # = (1 + m)*n*m\n",
      " |      m\n",
      " |      \n",
      " |      If there is more than one possible coefficient 0 is returned:\n",
      " |      \n",
      " |      >>> (n*m + m*n).coeff(n)\n",
      " |      0\n",
      " |      \n",
      " |      If there is only one possible coefficient, it is returned:\n",
      " |      \n",
      " |      >>> (n*m + x*m*n).coeff(m*n)\n",
      " |      x\n",
      " |      >>> (n*m + x*m*n).coeff(m*n, right=1)\n",
      " |      1\n",
      " |      \n",
      " |      See Also\n",
      " |      ========\n",
      " |      \n",
      " |      as_coefficient: separate the expression into a coefficient and factor\n",
      " |      as_coeff_Add: separate the additive constant from an expression\n",
      " |      as_coeff_Mul: separate the multiplicative constant from an expression\n",
      " |      as_independent: separate x-dependent terms/factors from others\n",
      " |      sympy.polys.polytools.Poly.coeff_monomial: efficiently find the single coefficient of a monomial in Poly\n",
      " |      sympy.polys.polytools.Poly.nth: like coeff_monomial but powers of monomial terms are used\n",
      " |  \n",
      " |  collect(self, syms, func=None, evaluate=True, exact=False, distribute_order_term=True)\n",
      " |      See the collect function in sympy.simplify\n",
      " |  \n",
      " |  combsimp(self)\n",
      " |      See the combsimp function in sympy.simplify\n",
      " |  \n",
      " |  compute_leading_term(self, x, logx=None)\n",
      " |      as_leading_term is only allowed for results of .series()\n",
      " |      This is a wrapper to compute a series first.\n",
      " |  \n",
      " |  conjugate(self)\n",
      " |      Returns the complex conjugate of 'self'.\n",
      " |  \n",
      " |  could_extract_minus_sign(self)\n",
      " |      Return True if self is not in a canonical form with respect\n",
      " |      to its sign.\n",
      " |      \n",
      " |      For most expressions, e, there will be a difference in e and -e.\n",
      " |      When there is, True will be returned for one and False for the\n",
      " |      other; False will be returned if there is no difference.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy.abc import x, y\n",
      " |      >>> e = x - y\n",
      " |      >>> {i.could_extract_minus_sign() for i in (e, -e)}\n",
      " |      {False, True}\n",
      " |  \n",
      " |  count_ops(self, visual=None)\n",
      " |      wrapper for count_ops that returns the operation count.\n",
      " |  \n",
      " |  diff(self, *symbols, **assumptions)\n",
      " |  \n",
      " |  dir(self, x, cdir)\n",
      " |  \n",
      " |  equals(self, other, failing_expression=False)\n",
      " |      Return True if self == other, False if it doesn't, or None. If\n",
      " |      failing_expression is True then the expression which did not simplify\n",
      " |      to a 0 will be returned instead of None.\n",
      " |      \n",
      " |      Explanation\n",
      " |      ===========\n",
      " |      \n",
      " |      If ``self`` is a Number (or complex number) that is not zero, then\n",
      " |      the result is False.\n",
      " |      \n",
      " |      If ``self`` is a number and has not evaluated to zero, evalf will be\n",
      " |      used to test whether the expression evaluates to zero. If it does so\n",
      " |      and the result has significance (i.e. the precision is either -1, for\n",
      " |      a Rational result, or is greater than 1) then the evalf value will be\n",
      " |      used to return True or False.\n",
      " |  \n",
      " |  expand(self, deep=True, modulus=None, power_base=True, power_exp=True, mul=True, log=True, multinomial=True, basic=True, **hints)\n",
      " |      Expand an expression using hints.\n",
      " |      \n",
      " |      See the docstring of the expand() function in sympy.core.function for\n",
      " |      more information.\n",
      " |  \n",
      " |  extract_additively(self, c)\n",
      " |      Return self - c if it's possible to subtract c from self and\n",
      " |      make all matching coefficients move towards zero, else return None.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy.abc import x, y\n",
      " |      >>> e = 2*x + 3\n",
      " |      >>> e.extract_additively(x + 1)\n",
      " |      x + 2\n",
      " |      >>> e.extract_additively(3*x)\n",
      " |      >>> e.extract_additively(4)\n",
      " |      >>> (y*(x + 1)).extract_additively(x + 1)\n",
      " |      >>> ((x + 1)*(x + 2*y + 1) + 3).extract_additively(x + 1)\n",
      " |      (x + 1)*(x + 2*y) + 3\n",
      " |      \n",
      " |      Sometimes auto-expansion will return a less simplified result\n",
      " |      than desired; gcd_terms might be used in such cases:\n",
      " |      \n",
      " |      >>> from sympy import gcd_terms\n",
      " |      >>> (4*x*(y + 1) + y).extract_additively(x)\n",
      " |      4*x*(y + 1) + x*(4*y + 3) - x*(4*y + 4) + y\n",
      " |      >>> gcd_terms(_)\n",
      " |      x*(4*y + 3) + y\n",
      " |      \n",
      " |      See Also\n",
      " |      ========\n",
      " |      extract_multiplicatively\n",
      " |      coeff\n",
      " |      as_coefficient\n",
      " |  \n",
      " |  extract_branch_factor(self, allow_half=False)\n",
      " |      Try to write self as ``exp_polar(2*pi*I*n)*z`` in a nice way.\n",
      " |      Return (z, n).\n",
      " |      \n",
      " |      >>> from sympy import exp_polar, I, pi\n",
      " |      >>> from sympy.abc import x, y\n",
      " |      >>> exp_polar(I*pi).extract_branch_factor()\n",
      " |      (exp_polar(I*pi), 0)\n",
      " |      >>> exp_polar(2*I*pi).extract_branch_factor()\n",
      " |      (1, 1)\n",
      " |      >>> exp_polar(-pi*I).extract_branch_factor()\n",
      " |      (exp_polar(I*pi), -1)\n",
      " |      >>> exp_polar(3*pi*I + x).extract_branch_factor()\n",
      " |      (exp_polar(x + I*pi), 1)\n",
      " |      >>> (y*exp_polar(-5*pi*I)*exp_polar(3*pi*I + 2*pi*x)).extract_branch_factor()\n",
      " |      (y*exp_polar(2*pi*x), -1)\n",
      " |      >>> exp_polar(-I*pi/2).extract_branch_factor()\n",
      " |      (exp_polar(-I*pi/2), 0)\n",
      " |      \n",
      " |      If allow_half is True, also extract exp_polar(I*pi):\n",
      " |      \n",
      " |      >>> exp_polar(I*pi).extract_branch_factor(allow_half=True)\n",
      " |      (1, 1/2)\n",
      " |      >>> exp_polar(2*I*pi).extract_branch_factor(allow_half=True)\n",
      " |      (1, 1)\n",
      " |      >>> exp_polar(3*I*pi).extract_branch_factor(allow_half=True)\n",
      " |      (1, 3/2)\n",
      " |      >>> exp_polar(-I*pi).extract_branch_factor(allow_half=True)\n",
      " |      (1, -1/2)\n",
      " |  \n",
      " |  extract_multiplicatively(self, c)\n",
      " |      Return None if it's not possible to make self in the form\n",
      " |      c * something in a nice way, i.e. preserving the properties\n",
      " |      of arguments of self.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy import symbols, Rational\n",
      " |      \n",
      " |      >>> x, y = symbols('x,y', real=True)\n",
      " |      \n",
      " |      >>> ((x*y)**3).extract_multiplicatively(x**2 * y)\n",
      " |      x*y**2\n",
      " |      \n",
      " |      >>> ((x*y)**3).extract_multiplicatively(x**4 * y)\n",
      " |      \n",
      " |      >>> (2*x).extract_multiplicatively(2)\n",
      " |      x\n",
      " |      \n",
      " |      >>> (2*x).extract_multiplicatively(3)\n",
      " |      \n",
      " |      >>> (Rational(1, 2)*x).extract_multiplicatively(3)\n",
      " |      x/6\n",
      " |  \n",
      " |  factor(self, *gens, **args)\n",
      " |      See the factor() function in sympy.polys.polytools\n",
      " |  \n",
      " |  fourier_series(self, limits=None)\n",
      " |      Compute fourier sine/cosine series of self.\n",
      " |      \n",
      " |      See the docstring of the :func:`fourier_series` in sympy.series.fourier\n",
      " |      for more information.\n",
      " |  \n",
      " |  fps(self, x=None, x0=0, dir=1, hyper=True, order=4, rational=True, full=False)\n",
      " |      Compute formal power power series of self.\n",
      " |      \n",
      " |      See the docstring of the :func:`fps` function in sympy.series.formal for\n",
      " |      more information.\n",
      " |  \n",
      " |  gammasimp(self)\n",
      " |      See the gammasimp function in sympy.simplify\n",
      " |  \n",
      " |  getO(self)\n",
      " |      Returns the additive O(..) symbol if there is one, else None.\n",
      " |  \n",
      " |  getn(self)\n",
      " |      Returns the order of the expression.\n",
      " |      \n",
      " |      Explanation\n",
      " |      ===========\n",
      " |      \n",
      " |      The order is determined either from the O(...) term. If there\n",
      " |      is no O(...) term, it returns None.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy import O\n",
      " |      >>> from sympy.abc import x\n",
      " |      >>> (1 + x + O(x**2)).getn()\n",
      " |      2\n",
      " |      >>> (1 + x).getn()\n",
      " |  \n",
      " |  integrate(self, *args, **kwargs)\n",
      " |      See the integrate function in sympy.integrals\n",
      " |  \n",
      " |  is_algebraic_expr(self, *syms)\n",
      " |      This tests whether a given expression is algebraic or not, in the\n",
      " |      given symbols, syms. When syms is not given, all free symbols\n",
      " |      will be used. The rational function does not have to be in expanded\n",
      " |      or in any kind of canonical form.\n",
      " |      \n",
      " |      This function returns False for expressions that are \"algebraic\n",
      " |      expressions\" with symbolic exponents. This is a simple extension to the\n",
      " |      is_rational_function, including rational exponentiation.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy import Symbol, sqrt\n",
      " |      >>> x = Symbol('x', real=True)\n",
      " |      >>> sqrt(1 + x).is_rational_function()\n",
      " |      False\n",
      " |      >>> sqrt(1 + x).is_algebraic_expr()\n",
      " |      True\n",
      " |      \n",
      " |      This function does not attempt any nontrivial simplifications that may\n",
      " |      result in an expression that does not appear to be an algebraic\n",
      " |      expression to become one.\n",
      " |      \n",
      " |      >>> from sympy import exp, factor\n",
      " |      >>> a = sqrt(exp(x)**2 + 2*exp(x) + 1)/(exp(x) + 1)\n",
      " |      >>> a.is_algebraic_expr(x)\n",
      " |      False\n",
      " |      >>> factor(a).is_algebraic_expr()\n",
      " |      True\n",
      " |      \n",
      " |      See Also\n",
      " |      ========\n",
      " |      is_rational_function()\n",
      " |      \n",
      " |      References\n",
      " |      ==========\n",
      " |      \n",
      " |      - https://en.wikipedia.org/wiki/Algebraic_expression\n",
      " |  \n",
      " |  is_meromorphic(self, x, a)\n",
      " |      This tests whether an expression is meromorphic as\n",
      " |      a function of the given symbol ``x`` at the point ``a``.\n",
      " |      \n",
      " |      This method is intended as a quick test that will return\n",
      " |      None if no decision can be made without simplification or\n",
      " |      more detailed analysis.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy import zoo, log, sin, sqrt\n",
      " |      >>> from sympy.abc import x\n",
      " |      \n",
      " |      >>> f = 1/x**2 + 1 - 2*x**3\n",
      " |      >>> f.is_meromorphic(x, 0)\n",
      " |      True\n",
      " |      >>> f.is_meromorphic(x, 1)\n",
      " |      True\n",
      " |      >>> f.is_meromorphic(x, zoo)\n",
      " |      True\n",
      " |      \n",
      " |      >>> g = x**log(3)\n",
      " |      >>> g.is_meromorphic(x, 0)\n",
      " |      False\n",
      " |      >>> g.is_meromorphic(x, 1)\n",
      " |      True\n",
      " |      >>> g.is_meromorphic(x, zoo)\n",
      " |      False\n",
      " |      \n",
      " |      >>> h = sin(1/x)*x**2\n",
      " |      >>> h.is_meromorphic(x, 0)\n",
      " |      False\n",
      " |      >>> h.is_meromorphic(x, 1)\n",
      " |      True\n",
      " |      >>> h.is_meromorphic(x, zoo)\n",
      " |      True\n",
      " |      \n",
      " |      Multivalued functions are considered meromorphic when their\n",
      " |      branches are meromorphic. Thus most functions are meromorphic\n",
      " |      everywhere except at essential singularities and branch points.\n",
      " |      In particular, they will be meromorphic also on branch cuts\n",
      " |      except at their endpoints.\n",
      " |      \n",
      " |      >>> log(x).is_meromorphic(x, -1)\n",
      " |      True\n",
      " |      >>> log(x).is_meromorphic(x, 0)\n",
      " |      False\n",
      " |      >>> sqrt(x).is_meromorphic(x, -1)\n",
      " |      True\n",
      " |      >>> sqrt(x).is_meromorphic(x, 0)\n",
      " |      False\n",
      " |  \n",
      " |  is_polynomial(self, *syms)\n",
      " |      Return True if self is a polynomial in syms and False otherwise.\n",
      " |      \n",
      " |      This checks if self is an exact polynomial in syms.  This function\n",
      " |      returns False for expressions that are \"polynomials\" with symbolic\n",
      " |      exponents.  Thus, you should be able to apply polynomial algorithms to\n",
      " |      expressions for which this returns True, and Poly(expr, \\*syms) should\n",
      " |      work if and only if expr.is_polynomial(\\*syms) returns True. The\n",
      " |      polynomial does not have to be in expanded form.  If no symbols are\n",
      " |      given, all free symbols in the expression will be used.\n",
      " |      \n",
      " |      This is not part of the assumptions system.  You cannot do\n",
      " |      Symbol('z', polynomial=True).\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy import Symbol\n",
      " |      >>> x = Symbol('x')\n",
      " |      >>> ((x**2 + 1)**4).is_polynomial(x)\n",
      " |      True\n",
      " |      >>> ((x**2 + 1)**4).is_polynomial()\n",
      " |      True\n",
      " |      >>> (2**x + 1).is_polynomial(x)\n",
      " |      False\n",
      " |      \n",
      " |      \n",
      " |      >>> n = Symbol('n', nonnegative=True, integer=True)\n",
      " |      >>> (x**n + 1).is_polynomial(x)\n",
      " |      False\n",
      " |      \n",
      " |      This function does not attempt any nontrivial simplifications that may\n",
      " |      result in an expression that does not appear to be a polynomial to\n",
      " |      become one.\n",
      " |      \n",
      " |      >>> from sympy import sqrt, factor, cancel\n",
      " |      >>> y = Symbol('y', positive=True)\n",
      " |      >>> a = sqrt(y**2 + 2*y + 1)\n",
      " |      >>> a.is_polynomial(y)\n",
      " |      False\n",
      " |      >>> factor(a)\n",
      " |      y + 1\n",
      " |      >>> factor(a).is_polynomial(y)\n",
      " |      True\n",
      " |      \n",
      " |      >>> b = (y**2 + 2*y + 1)/(y + 1)\n",
      " |      >>> b.is_polynomial(y)\n",
      " |      False\n",
      " |      >>> cancel(b)\n",
      " |      y + 1\n",
      " |      >>> cancel(b).is_polynomial(y)\n",
      " |      True\n",
      " |      \n",
      " |      See also .is_rational_function()\n",
      " |  \n",
      " |  is_rational_function(self, *syms)\n",
      " |      Test whether function is a ratio of two polynomials in the given\n",
      " |      symbols, syms. When syms is not given, all free symbols will be used.\n",
      " |      The rational function does not have to be in expanded or in any kind of\n",
      " |      canonical form.\n",
      " |      \n",
      " |      This function returns False for expressions that are \"rational\n",
      " |      functions\" with symbolic exponents.  Thus, you should be able to call\n",
      " |      .as_numer_denom() and apply polynomial algorithms to the result for\n",
      " |      expressions for which this returns True.\n",
      " |      \n",
      " |      This is not part of the assumptions system.  You cannot do\n",
      " |      Symbol('z', rational_function=True).\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy import Symbol, sin\n",
      " |      >>> from sympy.abc import x, y\n",
      " |      \n",
      " |      >>> (x/y).is_rational_function()\n",
      " |      True\n",
      " |      \n",
      " |      >>> (x**2).is_rational_function()\n",
      " |      True\n",
      " |      \n",
      " |      >>> (x/sin(y)).is_rational_function(y)\n",
      " |      False\n",
      " |      \n",
      " |      >>> n = Symbol('n', integer=True)\n",
      " |      >>> (x**n + 1).is_rational_function(x)\n",
      " |      False\n",
      " |      \n",
      " |      This function does not attempt any nontrivial simplifications that may\n",
      " |      result in an expression that does not appear to be a rational function\n",
      " |      to become one.\n",
      " |      \n",
      " |      >>> from sympy import sqrt, factor\n",
      " |      >>> y = Symbol('y', positive=True)\n",
      " |      >>> a = sqrt(y**2 + 2*y + 1)/y\n",
      " |      >>> a.is_rational_function(y)\n",
      " |      False\n",
      " |      >>> factor(a)\n",
      " |      (y + 1)/y\n",
      " |      >>> factor(a).is_rational_function(y)\n",
      " |      True\n",
      " |      \n",
      " |      See also is_algebraic_expr().\n",
      " |  \n",
      " |  leadterm(self, x, logx=None, cdir=0)\n",
      " |      Returns the leading term a*x**b as a tuple (a, b).\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy.abc import x\n",
      " |      >>> (1+x+x**2).leadterm(x)\n",
      " |      (1, 0)\n",
      " |      >>> (1/x**2+x+x**2).leadterm(x)\n",
      " |      (1, -2)\n",
      " |  \n",
      " |  limit(self, x, xlim, dir='+')\n",
      " |      Compute limit x->xlim.\n",
      " |  \n",
      " |  lseries(self, x=None, x0=0, dir='+', logx=None, cdir=0)\n",
      " |      Wrapper for series yielding an iterator of the terms of the series.\n",
      " |      \n",
      " |      Note: an infinite series will yield an infinite iterator. The following,\n",
      " |      for exaxmple, will never terminate. It will just keep printing terms\n",
      " |      of the sin(x) series::\n",
      " |      \n",
      " |        for term in sin(x).lseries(x):\n",
      " |            print term\n",
      " |      \n",
      " |      The advantage of lseries() over nseries() is that many times you are\n",
      " |      just interested in the next term in the series (i.e. the first term for\n",
      " |      example), but you don't know how many you should ask for in nseries()\n",
      " |      using the \"n\" parameter.\n",
      " |      \n",
      " |      See also nseries().\n",
      " |  \n",
      " |  normal(self)\n",
      " |      expression -> a/b\n",
      " |      \n",
      " |      See Also\n",
      " |      ========\n",
      " |      \n",
      " |      as_numer_denom: return ``(a, b)`` instead of ``a/b``\n",
      " |  \n",
      " |  nseries(self, x=None, x0=0, n=6, dir='+', logx=None, cdir=0)\n",
      " |      Wrapper to _eval_nseries if assumptions allow, else to series.\n",
      " |      \n",
      " |      If x is given, x0 is 0, dir='+', and self has x, then _eval_nseries is\n",
      " |      called. This calculates \"n\" terms in the innermost expressions and\n",
      " |      then builds up the final series just by \"cross-multiplying\" everything\n",
      " |      out.\n",
      " |      \n",
      " |      The optional ``logx`` parameter can be used to replace any log(x) in the\n",
      " |      returned series with a symbolic value to avoid evaluating log(x) at 0. A\n",
      " |      symbol to use in place of log(x) should be provided.\n",
      " |      \n",
      " |      Advantage -- it's fast, because we don't have to determine how many\n",
      " |      terms we need to calculate in advance.\n",
      " |      \n",
      " |      Disadvantage -- you may end up with less terms than you may have\n",
      " |      expected, but the O(x**n) term appended will always be correct and\n",
      " |      so the result, though perhaps shorter, will also be correct.\n",
      " |      \n",
      " |      If any of those assumptions is not met, this is treated like a\n",
      " |      wrapper to series which will try harder to return the correct\n",
      " |      number of terms.\n",
      " |      \n",
      " |      See also lseries().\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy import sin, log, Symbol\n",
      " |      >>> from sympy.abc import x, y\n",
      " |      >>> sin(x).nseries(x, 0, 6)\n",
      " |      x - x**3/6 + x**5/120 + O(x**6)\n",
      " |      >>> log(x+1).nseries(x, 0, 5)\n",
      " |      x - x**2/2 + x**3/3 - x**4/4 + O(x**5)\n",
      " |      \n",
      " |      Handling of the ``logx`` parameter --- in the following example the\n",
      " |      expansion fails since ``sin`` does not have an asymptotic expansion\n",
      " |      at -oo (the limit of log(x) as x approaches 0):\n",
      " |      \n",
      " |      >>> e = sin(log(x))\n",
      " |      >>> e.nseries(x, 0, 6)\n",
      " |      Traceback (most recent call last):\n",
      " |      ...\n",
      " |      PoleError: ...\n",
      " |      ...\n",
      " |      >>> logx = Symbol('logx')\n",
      " |      >>> e.nseries(x, 0, 6, logx=logx)\n",
      " |      sin(logx)\n",
      " |      \n",
      " |      In the following example, the expansion works but gives only an Order term\n",
      " |      unless the ``logx`` parameter is used:\n",
      " |      \n",
      " |      >>> e = x**y\n",
      " |      >>> e.nseries(x, 0, 2)\n",
      " |      O(log(x)**2)\n",
      " |      >>> e.nseries(x, 0, 2, logx=logx)\n",
      " |      exp(logx*y)\n",
      " |  \n",
      " |  nsimplify(self, constants=[], tolerance=None, full=False)\n",
      " |      See the nsimplify function in sympy.simplify\n",
      " |  \n",
      " |  powsimp(self, *args, **kwargs)\n",
      " |      See the powsimp function in sympy.simplify\n",
      " |  \n",
      " |  primitive(self)\n",
      " |      Return the positive Rational that can be extracted non-recursively\n",
      " |      from every term of self (i.e., self is treated like an Add). This is\n",
      " |      like the as_coeff_Mul() method but primitive always extracts a positive\n",
      " |      Rational (never a negative or a Float).\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy.abc import x\n",
      " |      >>> (3*(x + 1)**2).primitive()\n",
      " |      (3, (x + 1)**2)\n",
      " |      >>> a = (6*x + 2); a.primitive()\n",
      " |      (2, 3*x + 1)\n",
      " |      >>> b = (x/2 + 3); b.primitive()\n",
      " |      (1/2, x + 6)\n",
      " |      >>> (a*b).primitive() == (1, a*b)\n",
      " |      True\n",
      " |  \n",
      " |  radsimp(self, **kwargs)\n",
      " |      See the radsimp function in sympy.simplify\n",
      " |  \n",
      " |  ratsimp(self)\n",
      " |      See the ratsimp function in sympy.simplify\n",
      " |  \n",
      " |  removeO(self)\n",
      " |      Removes the additive O(..) symbol if there is one\n",
      " |  \n",
      " |  round(self, n=None)\n",
      " |      Return x rounded to the given decimal place.\n",
      " |      \n",
      " |      If a complex number would results, apply round to the real\n",
      " |      and imaginary components of the number.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy import pi, E, I, S, Number\n",
      " |      >>> pi.round()\n",
      " |      3\n",
      " |      >>> pi.round(2)\n",
      " |      3.14\n",
      " |      >>> (2*pi + E*I).round()\n",
      " |      6 + 3*I\n",
      " |      \n",
      " |      The round method has a chopping effect:\n",
      " |      \n",
      " |      >>> (2*pi + I/10).round()\n",
      " |      6\n",
      " |      >>> (pi/10 + 2*I).round()\n",
      " |      2*I\n",
      " |      >>> (pi/10 + E*I).round(2)\n",
      " |      0.31 + 2.72*I\n",
      " |      \n",
      " |      Notes\n",
      " |      =====\n",
      " |      \n",
      " |      The Python ``round`` function uses the SymPy ``round`` method so it\n",
      " |      will always return a SymPy number (not a Python float or int):\n",
      " |      \n",
      " |      >>> isinstance(round(S(123), -2), Number)\n",
      " |      True\n",
      " |  \n",
      " |  separate(self, deep=False, force=False)\n",
      " |      See the separate function in sympy.simplify\n",
      " |  \n",
      " |  series(self, x=None, x0=0, n=6, dir='+', logx=None, cdir=0)\n",
      " |      Series expansion of \"self\" around ``x = x0`` yielding either terms of\n",
      " |      the series one by one (the lazy series given when n=None), else\n",
      " |      all the terms at once when n != None.\n",
      " |      \n",
      " |      Returns the series expansion of \"self\" around the point ``x = x0``\n",
      " |      with respect to ``x`` up to ``O((x - x0)**n, x, x0)`` (default n is 6).\n",
      " |      \n",
      " |      If ``x=None`` and ``self`` is univariate, the univariate symbol will\n",
      " |      be supplied, otherwise an error will be raised.\n",
      " |      \n",
      " |      Parameters\n",
      " |      ==========\n",
      " |      \n",
      " |      expr : Expression\n",
      " |             The expression whose series is to be expanded.\n",
      " |      \n",
      " |      x : Symbol\n",
      " |          It is the variable of the expression to be calculated.\n",
      " |      \n",
      " |      x0 : Value\n",
      " |           The value around which ``x`` is calculated. Can be any value\n",
      " |           from ``-oo`` to ``oo``.\n",
      " |      \n",
      " |      n : Value\n",
      " |          The number of terms upto which the series is to be expanded.\n",
      " |      \n",
      " |      dir : String, optional\n",
      " |            The series-expansion can be bi-directional. If ``dir=\"+\"``,\n",
      " |            then (x->x0+). If ``dir=\"-\", then (x->x0-). For infinite\n",
      " |            ``x0`` (``oo`` or ``-oo``), the ``dir`` argument is determined\n",
      " |            from the direction of the infinity (i.e., ``dir=\"-\"`` for\n",
      " |            ``oo``).\n",
      " |      \n",
      " |      logx : optional\n",
      " |             It is used to replace any log(x) in the returned series with a\n",
      " |             symbolic value rather than evaluating the actual value.\n",
      " |      \n",
      " |      cdir : optional\n",
      " |             It stands for complex direction, and indicates the direction\n",
      " |             from which the expansion needs to be evaluated.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy import cos, exp, tan\n",
      " |      >>> from sympy.abc import x, y\n",
      " |      >>> cos(x).series()\n",
      " |      1 - x**2/2 + x**4/24 + O(x**6)\n",
      " |      >>> cos(x).series(n=4)\n",
      " |      1 - x**2/2 + O(x**4)\n",
      " |      >>> cos(x).series(x, x0=1, n=2)\n",
      " |      cos(1) - (x - 1)*sin(1) + O((x - 1)**2, (x, 1))\n",
      " |      >>> e = cos(x + exp(y))\n",
      " |      >>> e.series(y, n=2)\n",
      " |      cos(x + 1) - y*sin(x + 1) + O(y**2)\n",
      " |      >>> e.series(x, n=2)\n",
      " |      cos(exp(y)) - x*sin(exp(y)) + O(x**2)\n",
      " |      \n",
      " |      If ``n=None`` then a generator of the series terms will be returned.\n",
      " |      \n",
      " |      >>> term=cos(x).series(n=None)\n",
      " |      >>> [next(term) for i in range(2)]\n",
      " |      [1, -x**2/2]\n",
      " |      \n",
      " |      For ``dir=+`` (default) the series is calculated from the right and\n",
      " |      for ``dir=-`` the series from the left. For smooth functions this\n",
      " |      flag will not alter the results.\n",
      " |      \n",
      " |      >>> abs(x).series(dir=\"+\")\n",
      " |      x\n",
      " |      >>> abs(x).series(dir=\"-\")\n",
      " |      -x\n",
      " |      >>> f = tan(x)\n",
      " |      >>> f.series(x, 2, 6, \"+\")\n",
      " |      tan(2) + (1 + tan(2)**2)*(x - 2) + (x - 2)**2*(tan(2)**3 + tan(2)) +\n",
      " |      (x - 2)**3*(1/3 + 4*tan(2)**2/3 + tan(2)**4) + (x - 2)**4*(tan(2)**5 +\n",
      " |      5*tan(2)**3/3 + 2*tan(2)/3) + (x - 2)**5*(2/15 + 17*tan(2)**2/15 +\n",
      " |      2*tan(2)**4 + tan(2)**6) + O((x - 2)**6, (x, 2))\n",
      " |      \n",
      " |      >>> f.series(x, 2, 3, \"-\")\n",
      " |      tan(2) + (2 - x)*(-tan(2)**2 - 1) + (2 - x)**2*(tan(2)**3 + tan(2))\n",
      " |      + O((x - 2)**3, (x, 2))\n",
      " |      \n",
      " |      Returns\n",
      " |      =======\n",
      " |      \n",
      " |      Expr : Expression\n",
      " |          Series expansion of the expression about x0\n",
      " |      \n",
      " |      Raises\n",
      " |      ======\n",
      " |      \n",
      " |      TypeError\n",
      " |          If \"n\" and \"x0\" are infinity objects\n",
      " |      \n",
      " |      PoleError\n",
      " |          If \"x0\" is an infinity object\n",
      " |  \n",
      " |  taylor_term(self, n, x, *previous_terms)\n",
      " |      General method for the taylor term.\n",
      " |      \n",
      " |      This method is slow, because it differentiates n-times. Subclasses can\n",
      " |      redefine it to make it faster by using the \"previous_terms\".\n",
      " |  \n",
      " |  together(self, *args, **kwargs)\n",
      " |      See the together function in sympy.polys\n",
      " |  \n",
      " |  transpose(self)\n",
      " |  \n",
      " |  trigsimp(self, **args)\n",
      " |      See the trigsimp function in sympy.simplify\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Data and other attributes inherited from sympy.core.expr.Expr:\n",
      " |  \n",
      " |  is_scalar = True\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Methods inherited from sympy.core.basic.Basic:\n",
      " |  \n",
      " |  __getstate__(self)\n",
      " |  \n",
      " |  __reduce_ex__(self, protocol)\n",
      " |      Helper for pickle.\n",
      " |  \n",
      " |  as_dummy(self)\n",
      " |      Return the expression with any objects having structurally\n",
      " |      bound symbols replaced with unique, canonical symbols within\n",
      " |      the object in which they appear and having only the default\n",
      " |      assumption for commutativity being True. When applied to a\n",
      " |      symbol a new symbol having only the same commutativity will be\n",
      " |      returned.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy import Integral, Symbol\n",
      " |      >>> from sympy.abc import x\n",
      " |      >>> r = Symbol('r', real=True)\n",
      " |      >>> Integral(r, (r, x)).as_dummy()\n",
      " |      Integral(_0, (_0, x))\n",
      " |      >>> _.variables[0].is_real is None\n",
      " |      True\n",
      " |      >>> r.as_dummy()\n",
      " |      _r\n",
      " |      \n",
      " |      Notes\n",
      " |      =====\n",
      " |      \n",
      " |      Any object that has structurally bound variables should have\n",
      " |      a property, `bound_symbols` that returns those symbols\n",
      " |      appearing in the object.\n",
      " |  \n",
      " |  atoms(self, *types)\n",
      " |      Returns the atoms that form the current object.\n",
      " |      \n",
      " |      By default, only objects that are truly atomic and can't\n",
      " |      be divided into smaller pieces are returned: symbols, numbers,\n",
      " |      and number symbols like I and pi. It is possible to request\n",
      " |      atoms of any type, however, as demonstrated below.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy import I, pi, sin\n",
      " |      >>> from sympy.abc import x, y\n",
      " |      >>> (1 + x + 2*sin(y + I*pi)).atoms()\n",
      " |      {1, 2, I, pi, x, y}\n",
      " |      \n",
      " |      If one or more types are given, the results will contain only\n",
      " |      those types of atoms.\n",
      " |      \n",
      " |      >>> from sympy import Number, NumberSymbol, Symbol\n",
      " |      >>> (1 + x + 2*sin(y + I*pi)).atoms(Symbol)\n",
      " |      {x, y}\n",
      " |      \n",
      " |      >>> (1 + x + 2*sin(y + I*pi)).atoms(Number)\n",
      " |      {1, 2}\n",
      " |      \n",
      " |      >>> (1 + x + 2*sin(y + I*pi)).atoms(Number, NumberSymbol)\n",
      " |      {1, 2, pi}\n",
      " |      \n",
      " |      >>> (1 + x + 2*sin(y + I*pi)).atoms(Number, NumberSymbol, I)\n",
      " |      {1, 2, I, pi}\n",
      " |      \n",
      " |      Note that I (imaginary unit) and zoo (complex infinity) are special\n",
      " |      types of number symbols and are not part of the NumberSymbol class.\n",
      " |      \n",
      " |      The type can be given implicitly, too:\n",
      " |      \n",
      " |      >>> (1 + x + 2*sin(y + I*pi)).atoms(x) # x is a Symbol\n",
      " |      {x, y}\n",
      " |      \n",
      " |      Be careful to check your assumptions when using the implicit option\n",
      " |      since ``S(1).is_Integer = True`` but ``type(S(1))`` is ``One``, a special type\n",
      " |      of sympy atom, while ``type(S(2))`` is type ``Integer`` and will find all\n",
      " |      integers in an expression:\n",
      " |      \n",
      " |      >>> from sympy import S\n",
      " |      >>> (1 + x + 2*sin(y + I*pi)).atoms(S(1))\n",
      " |      {1}\n",
      " |      \n",
      " |      >>> (1 + x + 2*sin(y + I*pi)).atoms(S(2))\n",
      " |      {1, 2}\n",
      " |      \n",
      " |      Finally, arguments to atoms() can select more than atomic atoms: any\n",
      " |      sympy type (loaded in core/__init__.py) can be listed as an argument\n",
      " |      and those types of \"atoms\" as found in scanning the arguments of the\n",
      " |      expression recursively:\n",
      " |      \n",
      " |      >>> from sympy import Function, Mul\n",
      " |      >>> from sympy.core.function import AppliedUndef\n",
      " |      >>> f = Function('f')\n",
      " |      >>> (1 + f(x) + 2*sin(y + I*pi)).atoms(Function)\n",
      " |      {f(x), sin(y + I*pi)}\n",
      " |      >>> (1 + f(x) + 2*sin(y + I*pi)).atoms(AppliedUndef)\n",
      " |      {f(x)}\n",
      " |      \n",
      " |      >>> (1 + x + 2*sin(y + I*pi)).atoms(Mul)\n",
      " |      {I*pi, 2*sin(y + I*pi)}\n",
      " |  \n",
      " |  compare(self, other)\n",
      " |      Return -1, 0, 1 if the object is smaller, equal, or greater than other.\n",
      " |      \n",
      " |      Not in the mathematical sense. If the object is of a different type\n",
      " |      from the \"other\" then their classes are ordered according to\n",
      " |      the sorted_classes list.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy.abc import x, y\n",
      " |      >>> x.compare(y)\n",
      " |      -1\n",
      " |      >>> x.compare(x)\n",
      " |      0\n",
      " |      >>> y.compare(x)\n",
      " |      1\n",
      " |  \n",
      " |  copy(self)\n",
      " |  \n",
      " |  count(self, query)\n",
      " |      Count the number of matching subexpressions.\n",
      " |  \n",
      " |  dummy_eq(self, other, symbol=None)\n",
      " |      Compare two expressions and handle dummy symbols.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy import Dummy\n",
      " |      >>> from sympy.abc import x, y\n",
      " |      \n",
      " |      >>> u = Dummy('u')\n",
      " |      \n",
      " |      >>> (u**2 + 1).dummy_eq(x**2 + 1)\n",
      " |      True\n",
      " |      >>> (u**2 + 1) == (x**2 + 1)\n",
      " |      False\n",
      " |      \n",
      " |      >>> (u**2 + y).dummy_eq(x**2 + y, x)\n",
      " |      True\n",
      " |      >>> (u**2 + y).dummy_eq(x**2 + y, y)\n",
      " |      False\n",
      " |  \n",
      " |  find(self, query, group=False)\n",
      " |      Find all subexpressions matching a query.\n",
      " |  \n",
      " |  has(self, *patterns)\n",
      " |      Test whether any subexpression matches any of the patterns.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy import sin\n",
      " |      >>> from sympy.abc import x, y, z\n",
      " |      >>> (x**2 + sin(x*y)).has(z)\n",
      " |      False\n",
      " |      >>> (x**2 + sin(x*y)).has(x, y, z)\n",
      " |      True\n",
      " |      >>> x.has(x)\n",
      " |      True\n",
      " |      \n",
      " |      Note ``has`` is a structural algorithm with no knowledge of\n",
      " |      mathematics. Consider the following half-open interval:\n",
      " |      \n",
      " |      >>> from sympy.sets import Interval\n",
      " |      >>> i = Interval.Lopen(0, 5); i\n",
      " |      Interval.Lopen(0, 5)\n",
      " |      >>> i.args\n",
      " |      (0, 5, True, False)\n",
      " |      >>> i.has(4)  # there is no \"4\" in the arguments\n",
      " |      False\n",
      " |      >>> i.has(0)  # there *is* a \"0\" in the arguments\n",
      " |      True\n",
      " |      \n",
      " |      Instead, use ``contains`` to determine whether a number is in the\n",
      " |      interval or not:\n",
      " |      \n",
      " |      >>> i.contains(4)\n",
      " |      True\n",
      " |      >>> i.contains(0)\n",
      " |      False\n",
      " |      \n",
      " |      \n",
      " |      Note that ``expr.has(*patterns)`` is exactly equivalent to\n",
      " |      ``any(expr.has(p) for p in patterns)``. In particular, ``False`` is\n",
      " |      returned when the list of patterns is empty.\n",
      " |      \n",
      " |      >>> x.has()\n",
      " |      False\n",
      " |  \n",
      " |  is_hypergeometric(self, k)\n",
      " |  \n",
      " |  match(self, pattern, old=False)\n",
      " |      Pattern matching.\n",
      " |      \n",
      " |      Wild symbols match all.\n",
      " |      \n",
      " |      Return ``None`` when expression (self) does not match\n",
      " |      with pattern. Otherwise return a dictionary such that::\n",
      " |      \n",
      " |        pattern.xreplace(self.match(pattern)) == self\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy import Wild, Sum\n",
      " |      >>> from sympy.abc import x, y\n",
      " |      >>> p = Wild(\"p\")\n",
      " |      >>> q = Wild(\"q\")\n",
      " |      >>> r = Wild(\"r\")\n",
      " |      >>> e = (x+y)**(x+y)\n",
      " |      >>> e.match(p**p)\n",
      " |      {p_: x + y}\n",
      " |      >>> e.match(p**q)\n",
      " |      {p_: x + y, q_: x + y}\n",
      " |      >>> e = (2*x)**2\n",
      " |      >>> e.match(p*q**r)\n",
      " |      {p_: 4, q_: x, r_: 2}\n",
      " |      >>> (p*q**r).xreplace(e.match(p*q**r))\n",
      " |      4*x**2\n",
      " |      \n",
      " |      Structurally bound symbols are ignored during matching:\n",
      " |      \n",
      " |      >>> Sum(x, (x, 1, 2)).match(Sum(y, (y, 1, p)))\n",
      " |      {p_: 2}\n",
      " |      \n",
      " |      But they can be identified if desired:\n",
      " |      \n",
      " |      >>> Sum(x, (x, 1, 2)).match(Sum(q, (q, 1, p)))\n",
      " |      {p_: 2, q_: x}\n",
      " |      \n",
      " |      The ``old`` flag will give the old-style pattern matching where\n",
      " |      expressions and patterns are essentially solved to give the\n",
      " |      match. Both of the following give None unless ``old=True``:\n",
      " |      \n",
      " |      >>> (x - 2).match(p - x, old=True)\n",
      " |      {p_: 2*x - 2}\n",
      " |      >>> (2/x).match(p*x, old=True)\n",
      " |      {p_: 2/x**2}\n",
      " |  \n",
      " |  rcall(self, *args)\n",
      " |      Apply on the argument recursively through the expression tree.\n",
      " |      \n",
      " |      This method is used to simulate a common abuse of notation for\n",
      " |      operators. For instance in SymPy the the following will not work:\n",
      " |      \n",
      " |      ``(x+Lambda(y, 2*y))(z) == x+2*z``,\n",
      " |      \n",
      " |      however you can use\n",
      " |      \n",
      " |      >>> from sympy import Lambda\n",
      " |      >>> from sympy.abc import x, y, z\n",
      " |      >>> (x + Lambda(y, 2*y)).rcall(z)\n",
      " |      x + 2*z\n",
      " |  \n",
      " |  refine(self, assumption=True)\n",
      " |      See the refine function in sympy.assumptions\n",
      " |  \n",
      " |  replace(self, query, value, map=False, simultaneous=True, exact=None)\n",
      " |      Replace matching subexpressions of ``self`` with ``value``.\n",
      " |      \n",
      " |      If ``map = True`` then also return the mapping {old: new} where ``old``\n",
      " |      was a sub-expression found with query and ``new`` is the replacement\n",
      " |      value for it. If the expression itself doesn't match the query, then\n",
      " |      the returned value will be ``self.xreplace(map)`` otherwise it should\n",
      " |      be ``self.subs(ordered(map.items()))``.\n",
      " |      \n",
      " |      Traverses an expression tree and performs replacement of matching\n",
      " |      subexpressions from the bottom to the top of the tree. The default\n",
      " |      approach is to do the replacement in a simultaneous fashion so\n",
      " |      changes made are targeted only once. If this is not desired or causes\n",
      " |      problems, ``simultaneous`` can be set to False.\n",
      " |      \n",
      " |      In addition, if an expression containing more than one Wild symbol\n",
      " |      is being used to match subexpressions and the ``exact`` flag is None\n",
      " |      it will be set to True so the match will only succeed if all non-zero\n",
      " |      values are received for each Wild that appears in the match pattern.\n",
      " |      Setting this to False accepts a match of 0; while setting it True\n",
      " |      accepts all matches that have a 0 in them. See example below for\n",
      " |      cautions.\n",
      " |      \n",
      " |      The list of possible combinations of queries and replacement values\n",
      " |      is listed below:\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      Initial setup\n",
      " |      \n",
      " |      >>> from sympy import log, sin, cos, tan, Wild, Mul, Add\n",
      " |      >>> from sympy.abc import x, y\n",
      " |      >>> f = log(sin(x)) + tan(sin(x**2))\n",
      " |      \n",
      " |      1.1. type -> type\n",
      " |          obj.replace(type, newtype)\n",
      " |      \n",
      " |          When object of type ``type`` is found, replace it with the\n",
      " |          result of passing its argument(s) to ``newtype``.\n",
      " |      \n",
      " |          >>> f.replace(sin, cos)\n",
      " |          log(cos(x)) + tan(cos(x**2))\n",
      " |          >>> sin(x).replace(sin, cos, map=True)\n",
      " |          (cos(x), {sin(x): cos(x)})\n",
      " |          >>> (x*y).replace(Mul, Add)\n",
      " |          x + y\n",
      " |      \n",
      " |      1.2. type -> func\n",
      " |          obj.replace(type, func)\n",
      " |      \n",
      " |          When object of type ``type`` is found, apply ``func`` to its\n",
      " |          argument(s). ``func`` must be written to handle the number\n",
      " |          of arguments of ``type``.\n",
      " |      \n",
      " |          >>> f.replace(sin, lambda arg: sin(2*arg))\n",
      " |          log(sin(2*x)) + tan(sin(2*x**2))\n",
      " |          >>> (x*y).replace(Mul, lambda *args: sin(2*Mul(*args)))\n",
      " |          sin(2*x*y)\n",
      " |      \n",
      " |      2.1. pattern -> expr\n",
      " |          obj.replace(pattern(wild), expr(wild))\n",
      " |      \n",
      " |          Replace subexpressions matching ``pattern`` with the expression\n",
      " |          written in terms of the Wild symbols in ``pattern``.\n",
      " |      \n",
      " |          >>> a, b = map(Wild, 'ab')\n",
      " |          >>> f.replace(sin(a), tan(a))\n",
      " |          log(tan(x)) + tan(tan(x**2))\n",
      " |          >>> f.replace(sin(a), tan(a/2))\n",
      " |          log(tan(x/2)) + tan(tan(x**2/2))\n",
      " |          >>> f.replace(sin(a), a)\n",
      " |          log(x) + tan(x**2)\n",
      " |          >>> (x*y).replace(a*x, a)\n",
      " |          y\n",
      " |      \n",
      " |          Matching is exact by default when more than one Wild symbol\n",
      " |          is used: matching fails unless the match gives non-zero\n",
      " |          values for all Wild symbols:\n",
      " |      \n",
      " |          >>> (2*x + y).replace(a*x + b, b - a)\n",
      " |          y - 2\n",
      " |          >>> (2*x).replace(a*x + b, b - a)\n",
      " |          2*x\n",
      " |      \n",
      " |          When set to False, the results may be non-intuitive:\n",
      " |      \n",
      " |          >>> (2*x).replace(a*x + b, b - a, exact=False)\n",
      " |          2/x\n",
      " |      \n",
      " |      2.2. pattern -> func\n",
      " |          obj.replace(pattern(wild), lambda wild: expr(wild))\n",
      " |      \n",
      " |          All behavior is the same as in 2.1 but now a function in terms of\n",
      " |          pattern variables is used rather than an expression:\n",
      " |      \n",
      " |          >>> f.replace(sin(a), lambda a: sin(2*a))\n",
      " |          log(sin(2*x)) + tan(sin(2*x**2))\n",
      " |      \n",
      " |      3.1. func -> func\n",
      " |          obj.replace(filter, func)\n",
      " |      \n",
      " |          Replace subexpression ``e`` with ``func(e)`` if ``filter(e)``\n",
      " |          is True.\n",
      " |      \n",
      " |          >>> g = 2*sin(x**3)\n",
      " |          >>> g.replace(lambda expr: expr.is_Number, lambda expr: expr**2)\n",
      " |          4*sin(x**9)\n",
      " |      \n",
      " |      The expression itself is also targeted by the query but is done in\n",
      " |      such a fashion that changes are not made twice.\n",
      " |      \n",
      " |          >>> e = x*(x*y + 1)\n",
      " |          >>> e.replace(lambda x: x.is_Mul, lambda x: 2*x)\n",
      " |          2*x*(2*x*y + 1)\n",
      " |      \n",
      " |      When matching a single symbol, `exact` will default to True, but\n",
      " |      this may or may not be the behavior that is desired:\n",
      " |      \n",
      " |      Here, we want `exact=False`:\n",
      " |      \n",
      " |      >>> from sympy import Function\n",
      " |      >>> f = Function('f')\n",
      " |      >>> e = f(1) + f(0)\n",
      " |      >>> q = f(a), lambda a: f(a + 1)\n",
      " |      >>> e.replace(*q, exact=False)\n",
      " |      f(1) + f(2)\n",
      " |      >>> e.replace(*q, exact=True)\n",
      " |      f(0) + f(2)\n",
      " |      \n",
      " |      But here, the nature of matching makes selecting\n",
      " |      the right setting tricky:\n",
      " |      \n",
      " |      >>> e = x**(1 + y)\n",
      " |      >>> (x**(1 + y)).replace(x**(1 + a), lambda a: x**-a, exact=False)\n",
      " |      x\n",
      " |      >>> (x**(1 + y)).replace(x**(1 + a), lambda a: x**-a, exact=True)\n",
      " |      x**(-x - y + 1)\n",
      " |      >>> (x**y).replace(x**(1 + a), lambda a: x**-a, exact=False)\n",
      " |      x\n",
      " |      >>> (x**y).replace(x**(1 + a), lambda a: x**-a, exact=True)\n",
      " |      x**(1 - y)\n",
      " |      \n",
      " |      It is probably better to use a different form of the query\n",
      " |      that describes the target expression more precisely:\n",
      " |      \n",
      " |      >>> (1 + x**(1 + y)).replace(\n",
      " |      ... lambda x: x.is_Pow and x.exp.is_Add and x.exp.args[0] == 1,\n",
      " |      ... lambda x: x.base**(1 - (x.exp - 1)))\n",
      " |      ...\n",
      " |      x**(1 - y) + 1\n",
      " |      \n",
      " |      See Also\n",
      " |      ========\n",
      " |      \n",
      " |      subs: substitution of subexpressions as defined by the objects\n",
      " |            themselves.\n",
      " |      xreplace: exact node replacement in expr tree; also capable of\n",
      " |                using matching rules\n",
      " |  \n",
      " |  rewrite(self, *args, deep=True, **hints)\n",
      " |      Rewrite *self* using a defined rule.\n",
      " |      \n",
      " |      Rewriting transforms an expression to another, which is mathematically\n",
      " |      equivalent but structurally different. For example you can rewrite\n",
      " |      trigonometric functions as complex exponentials or combinatorial\n",
      " |      functions as gamma function.\n",
      " |      \n",
      " |      This method takes a *pattern* and a *rule* as positional arguments.\n",
      " |      *pattern* is optional parameter which defines the types of expressions\n",
      " |      that will be transformed. If it is not passed, all possible expressions\n",
      " |      will be rewritten. *rule* defines how the expression will be rewritten.\n",
      " |      \n",
      " |      Parameters\n",
      " |      ==========\n",
      " |      \n",
      " |      args : *rule*, or *pattern* and *rule*.\n",
      " |          - *pattern* is a type or an iterable of types.\n",
      " |          - *rule* can be any object.\n",
      " |      \n",
      " |      deep : bool, optional.\n",
      " |          If ``True``, subexpressions are recursively transformed. Default is\n",
      " |          ``True``.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      If *pattern* is unspecified, all possible expressions are transformed.\n",
      " |      \n",
      " |      >>> from sympy import cos, sin, exp, I\n",
      " |      >>> from sympy.abc import x\n",
      " |      >>> expr = cos(x) + I*sin(x)\n",
      " |      >>> expr.rewrite(exp)\n",
      " |      exp(I*x)\n",
      " |      \n",
      " |      Pattern can be a type or an iterable of types.\n",
      " |      \n",
      " |      >>> expr.rewrite(sin, exp)\n",
      " |      exp(I*x)/2 + cos(x) - exp(-I*x)/2\n",
      " |      >>> expr.rewrite([cos,], exp)\n",
      " |      exp(I*x)/2 + I*sin(x) + exp(-I*x)/2\n",
      " |      >>> expr.rewrite([cos, sin], exp)\n",
      " |      exp(I*x)\n",
      " |      \n",
      " |      Rewriting behavior can be implemented by defining ``_eval_rewrite()``\n",
      " |      method.\n",
      " |      \n",
      " |      >>> from sympy import Expr, sqrt, pi\n",
      " |      >>> class MySin(Expr):\n",
      " |      ...     def _eval_rewrite(self, rule, args, **hints):\n",
      " |      ...         x, = args\n",
      " |      ...         if rule == cos:\n",
      " |      ...             return cos(pi/2 - x, evaluate=False)\n",
      " |      ...         if rule == sqrt:\n",
      " |      ...             return sqrt(1 - cos(x)**2)\n",
      " |      >>> MySin(MySin(x)).rewrite(cos)\n",
      " |      cos(-cos(-x + pi/2) + pi/2)\n",
      " |      >>> MySin(x).rewrite(sqrt)\n",
      " |      sqrt(1 - cos(x)**2)\n",
      " |      \n",
      " |      Defining ``_eval_rewrite_as_[...]()`` method is supported for backwards\n",
      " |      compatibility reason. This may be removed in the future and using it is\n",
      " |      discouraged.\n",
      " |      \n",
      " |      >>> class MySin(Expr):\n",
      " |      ...     def _eval_rewrite_as_cos(self, *args, **hints):\n",
      " |      ...         x, = args\n",
      " |      ...         return cos(pi/2 - x, evaluate=False)\n",
      " |      >>> MySin(x).rewrite(cos)\n",
      " |      cos(-x + pi/2)\n",
      " |  \n",
      " |  simplify(self, **kwargs)\n",
      " |      See the simplify function in sympy.simplify\n",
      " |  \n",
      " |  subs(self, *args, **kwargs)\n",
      " |      Substitutes old for new in an expression after sympifying args.\n",
      " |      \n",
      " |      `args` is either:\n",
      " |        - two arguments, e.g. foo.subs(old, new)\n",
      " |        - one iterable argument, e.g. foo.subs(iterable). The iterable may be\n",
      " |           o an iterable container with (old, new) pairs. In this case the\n",
      " |             replacements are processed in the order given with successive\n",
      " |             patterns possibly affecting replacements already made.\n",
      " |           o a dict or set whose key/value items correspond to old/new pairs.\n",
      " |             In this case the old/new pairs will be sorted by op count and in\n",
      " |             case of a tie, by number of args and the default_sort_key. The\n",
      " |             resulting sorted list is then processed as an iterable container\n",
      " |             (see previous).\n",
      " |      \n",
      " |      If the keyword ``simultaneous`` is True, the subexpressions will not be\n",
      " |      evaluated until all the substitutions have been made.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy import pi, exp, limit, oo\n",
      " |      >>> from sympy.abc import x, y\n",
      " |      >>> (1 + x*y).subs(x, pi)\n",
      " |      pi*y + 1\n",
      " |      >>> (1 + x*y).subs({x:pi, y:2})\n",
      " |      1 + 2*pi\n",
      " |      >>> (1 + x*y).subs([(x, pi), (y, 2)])\n",
      " |      1 + 2*pi\n",
      " |      >>> reps = [(y, x**2), (x, 2)]\n",
      " |      >>> (x + y).subs(reps)\n",
      " |      6\n",
      " |      >>> (x + y).subs(reversed(reps))\n",
      " |      x**2 + 2\n",
      " |      \n",
      " |      >>> (x**2 + x**4).subs(x**2, y)\n",
      " |      y**2 + y\n",
      " |      \n",
      " |      To replace only the x**2 but not the x**4, use xreplace:\n",
      " |      \n",
      " |      >>> (x**2 + x**4).xreplace({x**2: y})\n",
      " |      x**4 + y\n",
      " |      \n",
      " |      To delay evaluation until all substitutions have been made,\n",
      " |      set the keyword ``simultaneous`` to True:\n",
      " |      \n",
      " |      >>> (x/y).subs([(x, 0), (y, 0)])\n",
      " |      0\n",
      " |      >>> (x/y).subs([(x, 0), (y, 0)], simultaneous=True)\n",
      " |      nan\n",
      " |      \n",
      " |      This has the added feature of not allowing subsequent substitutions\n",
      " |      to affect those already made:\n",
      " |      \n",
      " |      >>> ((x + y)/y).subs({x + y: y, y: x + y})\n",
      " |      1\n",
      " |      >>> ((x + y)/y).subs({x + y: y, y: x + y}, simultaneous=True)\n",
      " |      y/(x + y)\n",
      " |      \n",
      " |      In order to obtain a canonical result, unordered iterables are\n",
      " |      sorted by count_op length, number of arguments and by the\n",
      " |      default_sort_key to break any ties. All other iterables are left\n",
      " |      unsorted.\n",
      " |      \n",
      " |      >>> from sympy import sqrt, sin, cos\n",
      " |      >>> from sympy.abc import a, b, c, d, e\n",
      " |      \n",
      " |      >>> A = (sqrt(sin(2*x)), a)\n",
      " |      >>> B = (sin(2*x), b)\n",
      " |      >>> C = (cos(2*x), c)\n",
      " |      >>> D = (x, d)\n",
      " |      >>> E = (exp(x), e)\n",
      " |      \n",
      " |      >>> expr = sqrt(sin(2*x))*sin(exp(x)*x)*cos(2*x) + sin(2*x)\n",
      " |      \n",
      " |      >>> expr.subs(dict([A, B, C, D, E]))\n",
      " |      a*c*sin(d*e) + b\n",
      " |      \n",
      " |      The resulting expression represents a literal replacement of the\n",
      " |      old arguments with the new arguments. This may not reflect the\n",
      " |      limiting behavior of the expression:\n",
      " |      \n",
      " |      >>> (x**3 - 3*x).subs({x: oo})\n",
      " |      nan\n",
      " |      \n",
      " |      >>> limit(x**3 - 3*x, x, oo)\n",
      " |      oo\n",
      " |      \n",
      " |      If the substitution will be followed by numerical\n",
      " |      evaluation, it is better to pass the substitution to\n",
      " |      evalf as\n",
      " |      \n",
      " |      >>> (1/x).evalf(subs={x: 3.0}, n=21)\n",
      " |      0.333333333333333333333\n",
      " |      \n",
      " |      rather than\n",
      " |      \n",
      " |      >>> (1/x).subs({x: 3.0}).evalf(21)\n",
      " |      0.333333333333333314830\n",
      " |      \n",
      " |      as the former will ensure that the desired level of precision is\n",
      " |      obtained.\n",
      " |      \n",
      " |      See Also\n",
      " |      ========\n",
      " |      replace: replacement capable of doing wildcard-like matching,\n",
      " |               parsing of match, and conditional replacements\n",
      " |      xreplace: exact node replacement in expr tree; also capable of\n",
      " |                using matching rules\n",
      " |      sympy.core.evalf.EvalfMixin.evalf: calculates the given formula to a desired level of precision\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Class methods inherited from sympy.core.basic.Basic:\n",
      " |  \n",
      " |  fromiter(args, **assumptions) from sympy.core.assumptions.ManagedProperties\n",
      " |      Create a new object from an iterable.\n",
      " |      \n",
      " |      This is a convenience function that allows one to create objects from\n",
      " |      any iterable, without having to convert to a list or tuple first.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy import Tuple\n",
      " |      >>> Tuple.fromiter(i for i in range(5))\n",
      " |      (0, 1, 2, 3, 4)\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Readonly properties inherited from sympy.core.basic.Basic:\n",
      " |  \n",
      " |  args\n",
      " |      Returns a tuple of arguments of 'self'.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy import cot\n",
      " |      >>> from sympy.abc import x, y\n",
      " |      \n",
      " |      >>> cot(x).args\n",
      " |      (x,)\n",
      " |      \n",
      " |      >>> cot(x).args[0]\n",
      " |      x\n",
      " |      \n",
      " |      >>> (x*y).args\n",
      " |      (x, y)\n",
      " |      \n",
      " |      >>> (x*y).args[1]\n",
      " |      y\n",
      " |      \n",
      " |      Notes\n",
      " |      =====\n",
      " |      \n",
      " |      Never use self._args, always use self.args.\n",
      " |      Only use _args in __new__ when creating a new function.\n",
      " |      Don't override .args() from Basic (so that it's easy to\n",
      " |      change the interface in the future if needed).\n",
      " |  \n",
      " |  assumptions0\n",
      " |      Return object `type` assumptions.\n",
      " |      \n",
      " |      For example:\n",
      " |      \n",
      " |        Symbol('x', real=True)\n",
      " |        Symbol('x', integer=True)\n",
      " |      \n",
      " |      are different objects. In other words, besides Python type (Symbol in\n",
      " |      this case), the initial assumptions are also forming their typeinfo.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy import Symbol\n",
      " |      >>> from sympy.abc import x\n",
      " |      >>> x.assumptions0\n",
      " |      {'commutative': True}\n",
      " |      >>> x = Symbol(\"x\", positive=True)\n",
      " |      >>> x.assumptions0\n",
      " |      {'commutative': True, 'complex': True, 'extended_negative': False,\n",
      " |       'extended_nonnegative': True, 'extended_nonpositive': False,\n",
      " |       'extended_nonzero': True, 'extended_positive': True, 'extended_real':\n",
      " |       True, 'finite': True, 'hermitian': True, 'imaginary': False,\n",
      " |       'infinite': False, 'negative': False, 'nonnegative': True,\n",
      " |       'nonpositive': False, 'nonzero': True, 'positive': True, 'real':\n",
      " |       True, 'zero': False}\n",
      " |  \n",
      " |  canonical_variables\n",
      " |      Return a dictionary mapping any variable defined in\n",
      " |      ``self.bound_symbols`` to Symbols that do not clash\n",
      " |      with any free symbols in the expression.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy import Lambda\n",
      " |      >>> from sympy.abc import x\n",
      " |      >>> Lambda(x, 2*x).canonical_variables\n",
      " |      {x: _0}\n",
      " |  \n",
      " |  free_symbols\n",
      " |      Return from the atoms of self those which are free symbols.\n",
      " |      \n",
      " |      For most expressions, all symbols are free symbols. For some classes\n",
      " |      this is not true. e.g. Integrals use Symbols for the dummy variables\n",
      " |      which are bound variables, so Integral has a method to return all\n",
      " |      symbols except those. Derivative keeps track of symbols with respect\n",
      " |      to which it will perform a derivative; those are\n",
      " |      bound variables, too, so it has its own free_symbols method.\n",
      " |      \n",
      " |      Any other method that uses bound variables should implement a\n",
      " |      free_symbols method.\n",
      " |  \n",
      " |  func\n",
      " |      The top-level function in an expression.\n",
      " |      \n",
      " |      The following should hold for all objects::\n",
      " |      \n",
      " |          >> x == x.func(*x.args)\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy.abc import x\n",
      " |      >>> a = 2*x\n",
      " |      >>> a.func\n",
      " |      <class 'sympy.core.mul.Mul'>\n",
      " |      >>> a.args\n",
      " |      (2, x)\n",
      " |      >>> a.func(*a.args)\n",
      " |      2*x\n",
      " |      >>> a == a.func(*a.args)\n",
      " |      True\n",
      " |  \n",
      " |  is_antihermitian\n",
      " |  \n",
      " |  is_comparable\n",
      " |      Return True if self can be computed to a real number\n",
      " |      (or already is a real number) with precision, else False.\n",
      " |      \n",
      " |      Examples\n",
      " |      ========\n",
      " |      \n",
      " |      >>> from sympy import exp_polar, pi, I\n",
      " |      >>> (I*exp_polar(I*pi/2)).is_comparable\n",
      " |      True\n",
      " |      >>> (I*exp_polar(I*pi*2)).is_comparable\n",
      " |      False\n",
      " |      \n",
      " |      A False result does not mean that `self` cannot be rewritten\n",
      " |      into a form that would be comparable. For example, the\n",
      " |      difference computed below is zero but without simplification\n",
      " |      it does not evaluate to a zero with precision:\n",
      " |      \n",
      " |      >>> e = 2**pi*(1 + 2**pi)\n",
      " |      >>> dif = e - e.expand()\n",
      " |      >>> dif.is_comparable\n",
      " |      False\n",
      " |      >>> dif.n(2)._prec\n",
      " |      1\n",
      " |  \n",
      " |  is_extended_negative\n",
      " |  \n",
      " |  is_extended_nonnegative\n",
      " |  \n",
      " |  is_extended_nonpositive\n",
      " |  \n",
      " |  is_extended_positive\n",
      " |  \n",
      " |  is_negative\n",
      " |  \n",
      " |  is_nonnegative\n",
      " |  \n",
      " |  is_nonpositive\n",
      " |  \n",
      " |  is_polar\n",
      " |  \n",
      " |  is_positive\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Data and other attributes inherited from sympy.core.basic.Basic:\n",
      " |  \n",
      " |  is_Add = False\n",
      " |  \n",
      " |  is_AlgebraicNumber = False\n",
      " |  \n",
      " |  is_Boolean = False\n",
      " |  \n",
      " |  is_Derivative = False\n",
      " |  \n",
      " |  is_Dummy = False\n",
      " |  \n",
      " |  is_Equality = False\n",
      " |  \n",
      " |  is_Float = False\n",
      " |  \n",
      " |  is_Function = False\n",
      " |  \n",
      " |  is_Indexed = False\n",
      " |  \n",
      " |  is_Integer = False\n",
      " |  \n",
      " |  is_MatAdd = False\n",
      " |  \n",
      " |  is_MatMul = False\n",
      " |  \n",
      " |  is_Matrix = False\n",
      " |  \n",
      " |  is_Mul = False\n",
      " |  \n",
      " |  is_Not = False\n",
      " |  \n",
      " |  is_NumberSymbol = False\n",
      " |  \n",
      " |  is_Order = False\n",
      " |  \n",
      " |  is_Piecewise = False\n",
      " |  \n",
      " |  is_Point = False\n",
      " |  \n",
      " |  is_Poly = False\n",
      " |  \n",
      " |  is_Pow = False\n",
      " |  \n",
      " |  is_Relational = False\n",
      " |  \n",
      " |  is_Symbol = False\n",
      " |  \n",
      " |  is_Vector = False\n",
      " |  \n",
      " |  is_Wild = False\n",
      " |  \n",
      " |  is_symbol = False\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Methods inherited from sympy.printing.defaults.Printable:\n",
      " |  \n",
      " |  __repr__ = __str__(self)\n",
      " |  \n",
      " |  __str__(self)\n",
      " |      Return str(self).\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Methods inherited from sympy.core.evalf.EvalfMixin:\n",
      " |  \n",
      " |  evalf(self, n=15, subs=None, maxn=100, chop=False, strict=False, quad=None, verbose=False)\n",
      " |      Evaluate the given formula to an accuracy of *n* digits.\n",
      " |      \n",
      " |      Parameters\n",
      " |      ==========\n",
      " |      \n",
      " |      subs : dict, optional\n",
      " |          Substitute numerical values for symbols, e.g.\n",
      " |          ``subs={x:3, y:1+pi}``. The substitutions must be given as a\n",
      " |          dictionary.\n",
      " |      \n",
      " |      maxn : int, optional\n",
      " |          Allow a maximum temporary working precision of maxn digits.\n",
      " |      \n",
      " |      chop : bool or number, optional\n",
      " |          Specifies how to replace tiny real or imaginary parts in\n",
      " |          subresults by exact zeros.\n",
      " |      \n",
      " |          When ``True`` the chop value defaults to standard precision.\n",
      " |      \n",
      " |          Otherwise the chop value is used to determine the\n",
      " |          magnitude of \"small\" for purposes of chopping.\n",
      " |      \n",
      " |          >>> from sympy import N\n",
      " |          >>> x = 1e-4\n",
      " |          >>> N(x, chop=True)\n",
      " |          0.000100000000000000\n",
      " |          >>> N(x, chop=1e-5)\n",
      " |          0.000100000000000000\n",
      " |          >>> N(x, chop=1e-4)\n",
      " |          0\n",
      " |      \n",
      " |      strict : bool, optional\n",
      " |          Raise ``PrecisionExhausted`` if any subresult fails to\n",
      " |          evaluate to full accuracy, given the available maxprec.\n",
      " |      \n",
      " |      quad : str, optional\n",
      " |          Choose algorithm for numerical quadrature. By default,\n",
      " |          tanh-sinh quadrature is used. For oscillatory\n",
      " |          integrals on an infinite interval, try ``quad='osc'``.\n",
      " |      \n",
      " |      verbose : bool, optional\n",
      " |          Print debug information.\n",
      " |      \n",
      " |      Notes\n",
      " |      =====\n",
      " |      \n",
      " |      When Floats are naively substituted into an expression,\n",
      " |      precision errors may adversely affect the result. For example,\n",
      " |      adding 1e16 (a Float) to 1 will truncate to 1e16; if 1e16 is\n",
      " |      then subtracted, the result will be 0.\n",
      " |      That is exactly what happens in the following:\n",
      " |      \n",
      " |      >>> from sympy.abc import x, y, z\n",
      " |      >>> values = {x: 1e16, y: 1, z: 1e16}\n",
      " |      >>> (x + y - z).subs(values)\n",
      " |      0\n",
      " |      \n",
      " |      Using the subs argument for evalf is the accurate way to\n",
      " |      evaluate such an expression:\n",
      " |      \n",
      " |      >>> (x + y - z).evalf(subs=values)\n",
      " |      1.00000000000000\n",
      " |  \n",
      " |  n = evalf(self, n=15, subs=None, maxn=100, chop=False, strict=False, quad=None, verbose=False)\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(Rational)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2c5c4f25",
   "metadata": {},
   "source": [
    "#### 阅读更多相关内容"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0d7a48df",
   "metadata": {},
   "source": [
    "关于sympy和python之间的一些细微差别还有很多。以后在使用的过程中肯定会遇到一些意外情况。可以进一步阅读手册的第四章。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8c4032f5",
   "metadata": {},
   "source": [
    "### 基本操作符"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ebf397ed",
   "metadata": {},
   "source": [
    "这里主要是介绍sympy基本的数学表达式的操作与替换。进一步的学习讲放在后面。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "1823d992",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sympy import *\n",
    "x,y,z=symbols(\"x,y,z\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "589b4351",
   "metadata": {},
   "source": [
    "#### 替换操作"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e91fe41d",
   "metadata": {},
   "source": [
    "我们经常要使用一个表达式替换另一个表达式，这个时候我们可以使用subs函数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "3b31c392",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\cos{\\left(y \\right)} + 1$"
      ],
      "text/plain": [
       "cos(y) + 1"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "expr=cos(x)+1\n",
    "expr.subs(x,y)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2c8b5357",
   "metadata": {},
   "source": [
    "我们经常会在如下的几个场景中使用subs函数："
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1299c454",
   "metadata": {},
   "source": [
    "- 计算一个代数表达式在某一点的数值："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "8e4bfda2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle 2$"
      ],
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "expr.subs(x,0)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "938450a6",
   "metadata": {},
   "source": [
    "- 用一个新的表达式替换老的表达式："
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6283370e",
   "metadata": {},
   "source": [
    "比如我们想得到$x^{x^{x^{x}}}$:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "6e597d77",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle x^{y}$"
      ],
      "text/plain": [
       "x**y"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "expr=x**y\n",
    "expr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "84616d43",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle x^{x^{y}}$"
      ],
      "text/plain": [
       "x**(x**y)"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "expr=expr.subs(y,x**y)\n",
    "expr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "f9725705",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle x^{x^{x^{x}}}$"
      ],
      "text/plain": [
       "x**(x**(x**x))"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "expr=expr.subs(y,x**x)\n",
    "expr"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "87b7cf22",
   "metadata": {},
   "source": [
    "又或者我们要进行一些特殊的等价变换："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "9b1ace92",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle 2 \\sin{\\left(x \\right)} \\cos{\\left(x \\right)} + 2 \\cos^{2}{\\left(x \\right)} - 1$"
      ],
      "text/plain": [
       "2*sin(x)*cos(x) + 2*cos(x)**2 - 1"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "expr=sin(2*x)+cos(2*x)\n",
    "expand_trig(expr)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "99b926b7",
   "metadata": {},
   "source": [
    "如果我们并不想将$\\cos{2x}$展开，就可以使用这种方法。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "61a4c8fb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle 2 \\sin{\\left(x \\right)} \\cos{\\left(x \\right)} + \\cos{\\left(2 x \\right)}$"
      ],
      "text/plain": [
       "2*sin(x)*cos(x) + cos(2*x)"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "expr.subs(sin(2*x),2*sin(x)*cos(x))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3e76f108",
   "metadata": {},
   "source": [
    "**使用subs函数的一些技巧：**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "1a573235",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle 40$"
      ],
      "text/plain": [
       "40"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "expr=x**3+4*x*y-z\n",
    "expr.subs([(x,2),(y,4),(z,0)])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "a12899f2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle - 4 x^{3} - 2 x + y^{4} + 4 y^{2} + 3$"
      ],
      "text/plain": [
       "-4*x**3 - 2*x + y**4 + 4*y**2 + 3"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "expr=x**4-4*x**3+4*x**2-2*x+3\n",
    "replacements=[(x**i,y**i) for i in range(5) if i%2==0]\n",
    "expr.subs(replacements)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7fdfe9bf",
   "metadata": {},
   "source": [
    "#### 将字符串转成sympy表达式"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "57c3c2ae",
   "metadata": {},
   "source": [
    "sympify函数可以将字符串转成sympy表达式。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "44e42891",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle x^{2} + 3 x - \\frac{1}{2}$"
      ],
      "text/plain": [
       "x**2 + 3*x - 1/2"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "str_expr=\"x**2+3*x-1/2\"\n",
    "expr=sympify(str_expr)\n",
    "expr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "9639fe7d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\frac{1}{4} + \\frac{3 \\sqrt{3}}{2}$"
      ],
      "text/plain": [
       "1/4 + 3*sqrt(3)/2"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "expr.subs(x,sin(pi/3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "cc58fb0b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'x^{x^{x^{x}}}'"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "latex(expr)"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "原始单元格格式",
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
